{"record":{"id":"5ae44aac42a60a39","repo":"swc-project/swc","slug":"method-visittstype-not-implemented","errorCode":null,"errorMessage":"Method visitTsType not implemented.","messagePattern":"Method visitTsType not implemented\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/Visitor.ts","lineNumber":1734,"sourceCode":"        }\n        if (n.default) {\n            n.default = this.visitTsType(n.default);\n        }\n        n.name = this.visitIdentifierReference(n.name);\n        return n;\n    }\n\n    visitTsTypeAnnotation(\n        a: TsTypeAnnotation | undefined\n    ): TsTypeAnnotation | undefined {\n        if (a) {\n            a.typeAnnotation = this.visitTsType(a.typeAnnotation);\n        }\n        return a;\n    }\n\n    visitTsType(n: TsType): TsType {\n        throw new Error(\"Method visitTsType not implemented.\");\n    }\n\n    visitPatterns(nodes: Pattern[]): Pattern[] {\n        return nodes.map(this.visitPattern.bind(this));\n    }\n\n    visitImportDeclaration(n: ImportDeclaration): ImportDeclaration {\n        n.source = this.visitStringLiteral(n.source);\n        n.specifiers = this.visitImportSpecifiers(n.specifiers || []);\n        return n;\n    }\n\n    visitImportSpecifiers(nodes: ImportSpecifier[]): ImportSpecifier[] {\n        return nodes.map(this.visitImportSpecifier.bind(this));\n    }\n\n    visitImportSpecifier(node: ImportSpecifier): ImportSpecifier {\n        switch (node.type) {","sourceCodeStart":1716,"sourceCodeEnd":1752,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/packages/core/src/Visitor.ts#L1716-L1752","documentation":"The legacy JavaScript `Visitor` in @swc/core declares visitTsType but its base implementation only throws. TypeScript type nodes are reached via visitTsTypeAnnotation -> visitTsType whenever the traversal walks annotated nodes (function parameters, arrow return types, variable annotations). Any legacy-plugin visit of a TypeScript AST containing type annotations therefore crashes on the first type node unless the subclass overrides visitTsType.","triggerScenarios":"A legacy plugin visitor transforming a TS file with annotations such as `const x: number = 1` or `(a: string) => a`; arrow functions carrying returnType/typeParameters; any path reaching visitTsTypeAnnotation with a non-empty annotation while the subclass does not override visitTsType.","commonSituations":"Reusing an old JS plugin (written against plain JS) on .ts inputs after a monorepo migrates to TypeScript; enabling an existing legacy plugin for test fixtures that now include typed files.","solutions":["Override visitTsType in your subclass to return the node unchanged (`return n`), or deep-visit its variant if you actually need to mutate type nodes","Strip types before the plugin runs (feed JS output, or run a prior transform pass) so type annotations are never traversed","Migrate the plugin to the current visitor API, which handles TS nodes natively"],"exampleFix":"// before\nclass MyVisitor extends Visitor {}\n// -> Error: Method visitTsType not implemented.\n\n// after\nclass MyVisitor extends Visitor {\n    visitTsType(n) {\n        return n; // leave type nodes untouched\n    }\n}","handlingStrategy":"fallback","validationCode":"// Detect TypeScript type nodes before visiting so you can skip or strip them.\nfunction hasTsTypeNodes(program) {\n  return /\"TsKeywordType\"|\"TsTypeReference\"|\"TsTypeAnnotation\"/.test(JSON.stringify(program));\n}","typeGuard":null,"tryCatchPattern":"try {\n  program = new MyVisitor().visitProgram(program);\n} catch (e) {\n  if (e instanceof Error && /visitTsType not implemented/.test(e.message)) {\n    // subclass forgot the override — degrade to the untransformed program\n    return program;\n  }\n  throw e;\n}","preventionTips":["Always override visitTsType in legacy Visitor subclasses, even as a pass-through","Keep legacy JS plugins away from .ts inputs, or strip types before the plugin stage","Migrate legacy plugins to the current visitor API, which traverses TS nodes natively"],"tags":["swc","legacy-plugin","visitor","typescript","ast"],"backgroundTag":"visitor-method-not-implemented","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}