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",
],
}