3

I can't repro this on TS Playground. I have a method that returns an instance:

class Base {
  static selectOne<T extends typeof Base>(this: T): InstanceType<T> {}
}

class Foo extends Base {}
class Bar extends Base {}

This usually works fine with VS Code IntelliSense, e.g.:

const foo = Foo.selectOne(); // foo is type "Foo"

However, if I have a union of classes, it stops working:

const foo = (Foo as typeof Foo | typeof Bar).selectOne(); // foo is type "any"

This example works in TS Playground, it shows Foo | Bar, so there's probably something weird with my classes. As a workaround, I needed to add the instance type to the class:

class Base {
  static selectOne<T extends typeof Base>(this: T): T['instanceType'] {}
  static instanceType: Base;
}

class Foo extends Base {
  static instanceType: Foo;
}
class Bar extends Base {
  static instanceType: Bar;
}

What are some possible reasons why InstanceType returns any? I already spent several days trying to debug this. I can't share a reproducible example because there's hundreds of files.

Base tsconfig.json:

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "allowJs": true,
    "noEmit": true,
    "noEmitHelpers": true,
    "strict": true,
    "isolatedModules": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "baseUrl": "./",
    "noImplicitAny": true,
    "noImplicitOverride": true,
    "strictNullChecks": true,
    "useUnknownInCatchVariables": true,
    "resolveJsonModule": false,
    "types": ["node"],
    "experimentalDecorators": true,
    "noErrorTruncation": true,
  },
  "exclude": [
    "./node_modules",
    "./build",
  ],
}
Leo Jiang
  • 24,497
  • 49
  • 154
  • 284
  • 1
    If it works in the playground, then it works in Typescript. What version of typescript are you using? What does your `tsconfig.json` look like? – Alex Wayne May 28 '22 at 05:09
  • I can't paste hundreds of files into TS Playground, so I don't know if it works there. It's TS 4.6.4. I added the base tsconfig.json – Leo Jiang May 28 '22 at 05:41
  • So in your code base you paste this _exact_ example: https://tsplay.dev/mAy4Qm then the type for `foo` is `any`? If that example pulls in no other code it should work as you expect. If the problem is in code you haven't posted, then we dont have much to go on. – Alex Wayne May 28 '22 at 05:55
  • My question is "What are some possible reasons why InstanceType returns any?", not "look at my code" – Leo Jiang May 28 '22 at 05:56

0 Answers0