Skip to content

Commit

Permalink
Infer from constraints of type parameters in generic signatures
Browse files Browse the repository at this point in the history
  • Loading branch information
Andarist committed Jan 8, 2025
1 parent c0b3ff2 commit 80f7af3
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 2 deletions.
14 changes: 12 additions & 2 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26842,8 +26842,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const targetSignatures = getSignaturesOfType(target, kind);
const targetLen = targetSignatures.length;
for (let i = 0; i < targetLen; i++) {
const sourceIndex = Math.max(sourceLen - targetLen + i, 0);
inferFromSignature(getBaseSignature(sourceSignatures[sourceIndex]), getErasedSignature(targetSignatures[i]));
const sourceSignature = sourceSignatures[Math.max(sourceLen - targetLen + i, 0)];
const targetSignature = targetSignatures[i];
if (targetSignature.typeParameters && targetSignature.typeParameters.length === sourceSignature.typeParameters?.length) {
for (let j = 0; j < targetSignature.typeParameters.length; j++) {
const sourceTypeParameter = sourceSignature.typeParameters[j];
const targetTypeParameter = targetSignature.typeParameters[j];
if (sourceTypeParameter.constraint && targetTypeParameter.constraint) {
inferFromTypes(sourceTypeParameter.constraint, targetTypeParameter.constraint);
}
}
}
inferFromSignature(getBaseSignature(sourceSignature), getErasedSignature(targetSignature));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//// [tests/cases/compiler/inferenceFromGenericSignatureTypeParamConstraints1.ts] ////

=== inferenceFromGenericSignatureTypeParamConstraints1.ts ===
// https://github.com/microsoft/TypeScript/issues/41040

type InferGenericConstraint<Fn> =
>InferGenericConstraint : Symbol(InferGenericConstraint, Decl(inferenceFromGenericSignatureTypeParamConstraints1.ts, 0, 0))
>Fn : Symbol(Fn, Decl(inferenceFromGenericSignatureTypeParamConstraints1.ts, 2, 28))

Fn extends <T extends infer Constraint>(arg: T) => any
>Fn : Symbol(Fn, Decl(inferenceFromGenericSignatureTypeParamConstraints1.ts, 2, 28))
>T : Symbol(T, Decl(inferenceFromGenericSignatureTypeParamConstraints1.ts, 3, 16))
>Constraint : Symbol(Constraint, Decl(inferenceFromGenericSignatureTypeParamConstraints1.ts, 3, 31))
>arg : Symbol(arg, Decl(inferenceFromGenericSignatureTypeParamConstraints1.ts, 3, 44))
>T : Symbol(T, Decl(inferenceFromGenericSignatureTypeParamConstraints1.ts, 3, 16))

? Constraint
>Constraint : Symbol(Constraint, Decl(inferenceFromGenericSignatureTypeParamConstraints1.ts, 3, 31))

: never;

type GenericFunctionExample = <T extends number>(arg: T) => void;
>GenericFunctionExample : Symbol(GenericFunctionExample, Decl(inferenceFromGenericSignatureTypeParamConstraints1.ts, 5, 16))
>T : Symbol(T, Decl(inferenceFromGenericSignatureTypeParamConstraints1.ts, 7, 31))
>arg : Symbol(arg, Decl(inferenceFromGenericSignatureTypeParamConstraints1.ts, 7, 49))
>T : Symbol(T, Decl(inferenceFromGenericSignatureTypeParamConstraints1.ts, 7, 31))

type InferredConstraint = InferGenericConstraint<GenericFunctionExample>;
>InferredConstraint : Symbol(InferredConstraint, Decl(inferenceFromGenericSignatureTypeParamConstraints1.ts, 7, 65))
>InferGenericConstraint : Symbol(InferGenericConstraint, Decl(inferenceFromGenericSignatureTypeParamConstraints1.ts, 0, 0))
>GenericFunctionExample : Symbol(GenericFunctionExample, Decl(inferenceFromGenericSignatureTypeParamConstraints1.ts, 5, 16))

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//// [tests/cases/compiler/inferenceFromGenericSignatureTypeParamConstraints1.ts] ////

=== inferenceFromGenericSignatureTypeParamConstraints1.ts ===
// https://github.com/microsoft/TypeScript/issues/41040

type InferGenericConstraint<Fn> =
>InferGenericConstraint : InferGenericConstraint<Fn>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^

Fn extends <T extends infer Constraint>(arg: T) => any
>arg : T
> : ^

? Constraint
: never;

type GenericFunctionExample = <T extends number>(arg: T) => void;
>GenericFunctionExample : GenericFunctionExample
> : ^^^^^^^^^^^^^^^^^^^^^^
>arg : T
> : ^

type InferredConstraint = InferGenericConstraint<GenericFunctionExample>;
>InferredConstraint : number
> : ^^^^^^

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// @noEmit: true
// @strict: true

// https://github.com/microsoft/TypeScript/issues/41040

type InferGenericConstraint<Fn> =
Fn extends <T extends infer Constraint>(arg: T) => any
? Constraint
: never;

type GenericFunctionExample = <T extends number>(arg: T) => void;

type InferredConstraint = InferGenericConstraint<GenericFunctionExample>;

0 comments on commit 80f7af3

Please sign in to comment.