microsoft / microsoft/TypeScript
Type narrowing discards template type on this-typed return value
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 132
Description
Bug Report
🔎 Search Terms
type narrowing template constraint
🕗 Version & Regression Information
Bug occurs in every version on the playground
⏯ Playground Link
Playground link with relevant code
💻 Code
abstract class Foo {
abstract clone(): this;
}
function cloneMe<T extends Foo|Date>(x: T): T {
if (x instanceof Foo) return x.clone();
// These casts are necessary because of https://github.com/microsoft/TypeScript/issues/38309.
return new Date(x as Date) as T;
}
🙁 Actual behavior
Type 'Foo & Foo' is not assignable to type 'T'. 'Foo & Foo' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Foo | Date'.
🙂 Expected behavior
No errors; just like the instanceof check narrows x to Foo & T, the this return type of x.clone() should also be Foo & T rather than degrading to Foo & Foo.
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
Start with the linked TypeScript Playground example and inspect the type narrowing and polymorphic this return behavior involved in cloneMe. The issue is done when the x.clone() return is preserved as Foo & T and the example type-checks without casts or errors.
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
- Clearly specified
- Newbie friendliness
- 35/100