Skip to content

Commit

Permalink
Fixed an issue with not being able to use mapped type over union cons…
Browse files Browse the repository at this point in the history
…traint as rest param
  • Loading branch information
Andarist committed Jul 19, 2022
1 parent aa2b235 commit 778e73c
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12318,7 +12318,7 @@ namespace ts {
const typeVariable = getHomomorphicTypeVariable(type);
if (typeVariable && !type.declaration.nameType) {
const constraint = getConstraintOfTypeParameter(typeVariable);
if (constraint && isArrayOrTupleType(constraint)) {
if (constraint && everyType(constraint, isArrayOrTupleType)) {
return instantiateType(type, prependTypeMapping(typeVariable, constraint, type.mapper));
}
}
Expand Down Expand Up @@ -19860,7 +19860,8 @@ namespace ts {
return varianceResult;
}
}
else if (isReadonlyArrayType(target) ? isArrayOrTupleType(source) : isArrayType(target) && isTupleType(source) && !source.target.readonly) {
// TODO: andarist
else if (isReadonlyArrayType(target) ? everyType(source, isArrayOrTupleType) : isArrayType(target) && isTupleType(source) && !source.target.readonly) {
if (relation !== identityRelation) {
return isRelatedTo(getIndexTypeOfType(source, numberType) || anyType, getIndexTypeOfType(target, numberType) || anyType, RecursionFlags.Both, reportErrors);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
=== tests/cases/compiler/restParamUsingMappedTypeOverUnionConstraint.ts ===
// repro 29919#issuecomment-470948453

type Mapped<T> = { [P in keyof T]: T[P] extends string ? [number] : [string] }
>Mapped : Symbol(Mapped, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 0, 0))
>T : Symbol(T, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 2, 12))
>P : Symbol(P, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 2, 20))
>T : Symbol(T, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 2, 12))
>T : Symbol(T, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 2, 12))
>P : Symbol(P, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 2, 20))

declare function test<T extends [number] | [string]>(
>test : Symbol(test, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 2, 78))
>T : Symbol(T, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 4, 22))

args: T,
>args : Symbol(args, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 4, 53))
>T : Symbol(T, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 4, 22))

fn: (...args: Mapped<T>) => void
>fn : Symbol(fn, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 5, 10))
>args : Symbol(args, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 6, 7))
>Mapped : Symbol(Mapped, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 0, 0))
>T : Symbol(T, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 4, 22))

): number

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
=== tests/cases/compiler/restParamUsingMappedTypeOverUnionConstraint.ts ===
// repro 29919#issuecomment-470948453

type Mapped<T> = { [P in keyof T]: T[P] extends string ? [number] : [string] }
>Mapped : Mapped<T>

declare function test<T extends [number] | [string]>(
>test : <T extends [number] | [string]>(args: T, fn: (...args: Mapped<T>) => void) => number

args: T,
>args : T

fn: (...args: Mapped<T>) => void
>fn : (...args: Mapped<T>) => void
>args : Mapped<T>

): number

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

// repro 29919#issuecomment-470948453

type Mapped<T> = { [P in keyof T]: T[P] extends string ? [number] : [string] }

declare function test<T extends [number] | [string]>(
args: T,
fn: (...args: Mapped<T>) => void
): number

0 comments on commit 778e73c

Please sign in to comment.