microsoft / microsoft/TypeScript
Narrowing types with private functions with `this` return type fails
@weswigham is already working on this.
Since Jul 1, 2021.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.4k
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 117
Description
Bug Report
I found that a generic type may be evaluated as incompatible while in fact it should be compatible. In my particular case I have a few generic types / classes that have a type argument constrained to MyClass.
I also have a conditional type with a generic argument that is "less" constrained to a union type of MyClass and a different class that has a generic.
// Conditional type with a generic constrained to either MyClass or something else
type ConditionalType<T extends MyClass | string> =
T extends MyClass ? MyGenericType<T> : T;
In the given constellation I get the following error:
Type 'MyClass & T' does not satisfy the constraint 'MyClass'.
Property 'fn' is missing in type 'MyClass & T' but required in type 'MyClass'.(2344)
I found that these prerequisites have to be met to reproduce the error:
- The class (
MyClass) that we constrain the generics arguments to has a function that returns athistype.
Edit: Or no type annotation, no matter what the inferred type is. Other return type annotations, e.g.: stringwork. - This function is either
protectedorprivate.
🔎 Search Terms
this type, generic, conditional types
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about: seems to me that none apply.
⏯ Playground Link
Playground link with relevant code
💻 Code
// The class to constrain to in the generic types
class MyClass {
constructor(public name: string) {}
protected fn(): this {
return this;
}
}
// A generic type with a type argument constrained to MyClass
type MyGenericType<T extends MyClass> = T;
// Conditional type with a generic constrained to either MyClass or something else
type ConditionalType<T extends MyClass | string> =
T extends MyClass ? MyGenericType<T> : T;
🙁 Actual behavior
Although the condition in the mapped type constrains the given type to extend MyClass it is not compatible as the type here evaluates to MyClass & T.
🙂 Expected behavior
I would expect that the condition in the type narrows the type as given in the condition.
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.
Assessment
This issue has not been assessed yet.