microsoft / microsoft/TypeScript
Generic constraint generates a TS2344
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.x, 3.8.1, 3.9.x (next)
Search Terms: Generic constraint 2344
Code
type KeyOf<T> = keyof ((T extends any ? (k: T)=>void : never) extends ((k: infer I)=>void) ? I : never);
type Constraint<T> = KeyOf<T> extends never
? any
// : KeyOf<any> extends KeyOf<T>
// ? any
: (
'a' extends KeyOf<T>
? never
: any
);
type ForceConstraint<T> = T extends Constraint<T> ? T : never;
interface Interface<T extends Constraint<T>> {
b: string;
}
type Infer<CB> = CB extends () => infer TReturn
? ForceConstraint<TReturn>
: never;
type InferWithConstraint<CB> = ForceConstraint<Infer<CB>>;
type InferInterfaceFromCallback<CB> = Interface<InferWithConstraint<CB>>; // invalid => NOT OK
type InferInterfaceFromCallback1<CB> = Interface<Infer<CB>;> // invalid too => NOT OK
// just debug purpose
type A1 = Interface<unknown>;
type A2 = Interface<any>; // invalid => OK
type A3 = Interface<never>;
type A4 = Interface<undefined>;
type A5 = Interface<number>;
type A6 = Interface<string>;
type A7 = Interface<null>;
type A8 = Interface<object>;
type A9 = Interface<{}>;
type A_FAIL1 = Interface<{ a: 'b' }>; // invalid => OK
type A_FAIL2 = Interface<{ a: 'b' } | 1>; // invalid => OK
Expected behavior:
type InferInterfaceFromCallback<CB> = Interface<InferWithConstraint<CB>>;
Should be valid
Explanation:
So, i was trying to apply a specific constraint on a generic type.
Constraint<T> 'returns' never if T contains a property called a, else it returns any
ForceConstraint<T> tries to help typescript to know if T is valid, else it returns never
Interface<T extends Constraint<T>> forces its generic type to respect Constraint
Infer<CB> infers the return type of CB and ensures it follows Constraint
InferWithConstraint<CB> forces again Infer<CB> to be compliant with Constraint (even if it is already)
So Interface<InferWithConstraint<CB>> should be valid, sadly, typescript reports:
TS2344: Type 'ForceConstraint<Infer<CB>>' does not satisfy the constraint 'Constraint<ForceConstraint<Infer<CB>>>'.
Potentially related issues:
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 provided Playground Link and reproduce the TS2344 diagnostic using the minimal generic-type example. Compare the expected validity of Interface<InferWithConstraint> with the reported constraint error and review related issues 31736 and 34604. Done means the valid type alias no longer produces TS2344 while the invalid examples remain rejected.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100