microsoft / microsoft/TypeScript
this type in conditional type false clause is incorrectly typed
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 132
Description
TypeScript Version: 3.7.3
Search Terms:
generic type this widening incorrect
Code
type Option1 = { run(this: { b: 1 }): void }
function f1(options: Option1) { return options }
// `this` is correctly typed as `{ b: 1 }`
f1({ run() { this.b } })
type Option2<Config> = Config extends Record<string, any> ? {
config: Config,
run(this: Config): void
} : {
run(arg: { b: 1 }): void
}
function f2<Config>(options: Option2<Config>) { return options }
// `this` is correctly typed as `{ a: number }`
f2({ config: { a: 1 }, run() { this.a } })
// `arg` is correctly typed as `{ b: 1 }`
f2({ run(arg) { arg.b } })
type Option3<Config> = Config extends Record<string, any> ? {
config: Config,
run(this: Config): void
} : {
run(this: { b: 1 }): void
}
function f3<Config>(options: Option3<Config>) { return options }
// `this` is correctly typed as `{ a: number }`
f3({ config: { a: 1 }, run() { this.a } })
// `this` is widen to what `Config` extends to. In this case `Record<string, any>`
f3({ run() { this.b } })
Expected behavior:
this in f3({ run() { this.b } }) should be typed as in this in f1() and arg in f2()
Actual behavior:
this in f3({ run() { this.b } }) is typed as the base type of Config (Record<string,any> in the example above)
Playground Link:
Playground Link
Related Issues:
Some maybe related issues:
https://github.com/microsoft/TypeScript/issues/32990
https://github.com/microsoft/TypeScript/issues/30152
https://github.com/microsoft/TypeScript/issues/13995
I also recall there were some discussion about type and Record<>, but that is in the gitter channel and I can't find relevant issue or doc about it.
I think this is different than the related issues above because this does not involve union type.
This is about the false condition of the conditional type Config extends Record<string, any> ? ... : ... do not use the generic type Config and should not be affected by it.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the examples in the linked TypeScript Playground, comparing the contextual type of this in f1, f2, and f3. Investigate conditional-type contextual typing for the false clause; done means the f3 callback's this is typed as { b: 1 } rather than the widened base type, without regressing the other examples.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100