Closed
Description
Bug Report
🔎 Search Terms
- js inference
- javascript inference
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about differing type inference for JS and TS
💻 Code
JavaScript:
/** @template R */
export class Action {
/**
* @returns {R}
*/
action() {
throw new Error("This method is abstract!")
}
/**
* @template {new () => Action<any>} C
* @this {C}
* @return {C extends new () => Action<infer T> ? T : never}
*/
static run() {
return new this().action()
}
}
/** @extends {Action<number>} */
export class Foo extends Action {
action() {
return 1
}
}
const handle = Foo.run()
Compiler Options
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"alwaysStrict": true,
"esModuleInterop": true,
"checkJs": true,
"allowJs": true,
"declaration": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"target": "ES2017",
"jsx": "react",
"module": "ESNext",
"moduleResolution": "node"
}
}
Playground Link: Provided
TypeScript:
export abstract class Action<R> {
action(): R {
throw new Error("This method is abstract!")
}
static run<C extends new () => Action<any>>(
this: C,
): C extends new () => Action<infer T> ? T : never {
return new this().action()
}
}
export class Foo extends Action<number> {
action() {
return 1
}
}
const handle = Foo.run()
Output
export class Action {
action() {
throw new Error("This method is abstract!");
}
static run() {
return new this().action();
}
}
export class Foo extends Action {
action() {
return 1;
}
}
const handle = Foo.run();
Compiler Options
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"alwaysStrict": true,
"esModuleInterop": true,
"declaration": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"target": "ES2017",
"jsx": "react",
"module": "ESNext",
"moduleResolution": "node"
}
}
Playground Link: Provided
🙁 Actual behavior
The inferred type for handle
to in the JS version is any
, and the --noImplicitAny
option is not respected.
🙂 Expected behavior
The inferred type for handle
to be number
for both, as the types are fully equivalent.