diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b975b9848853d..c030329ef2d4d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13861,7 +13861,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const typeVariable = getHomomorphicTypeVariable(type); if (typeVariable && !type.declaration.nameType) { const constraint = getConstraintOfTypeParameter(typeVariable); - if (constraint && isArrayType(constraint)) { + if (constraint && everyType(constraint, isArrayOrTupleType)) { return instantiateType(type, prependTypeMapping(typeVariable, constraint, type.mapper)); } } @@ -21679,7 +21679,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return varianceResult; } } - else if (isReadonlyArrayType(target) ? isArrayOrTupleType(source) : isArrayType(target) && isTupleType(source) && !source.target.readonly) { + else if (isReadonlyArrayType(target) ? everyType(source, isArrayOrTupleType) : isArrayType(target) && everyType(source, t => isTupleType(t) && !t.target.readonly)) { if (relation !== identityRelation) { return isRelatedTo(getIndexTypeOfType(source, numberType) || anyType, getIndexTypeOfType(target, numberType) || anyType, RecursionFlags.Both, reportErrors); } @@ -29251,7 +29251,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { getContextualType(node, contextFlags); const instantiatedType = instantiateContextualType(contextualType, node, contextFlags); if (instantiatedType && !(contextFlags && contextFlags & ContextFlags.NoConstraints && instantiatedType.flags & TypeFlags.TypeVariable)) { - const apparentType = mapType(instantiatedType, getApparentType, /*noReductions*/ true); + const apparentType = mapType( + instantiatedType, + // When obtaining apparent type of *contextual* type we don't want to get apparent type of mapped types. + // That would evaluate mapped types with array or tuple type constraints too eagerly + // and thus it would prevent `getTypeOfPropertyOfContextualType` from obtaining per-position contextual type for elements of array literal expressions. + // Apparent type of other mapped types is already the mapped type itself so we can just avoid calling `getApparentType` here for all mapped types. + t => getObjectFlags(t) & ObjectFlags.Mapped ? t : getApparentType(t), + /*noReductions*/ true + ); return apparentType.flags & TypeFlags.Union && isObjectLiteralExpression(node) ? discriminateContextualTypeByObjectMembers(node, apparentType as UnionType) : apparentType.flags & TypeFlags.Union && isJsxAttributes(node) ? discriminateContextualTypeByJSXAttributes(node, apparentType as UnionType) : apparentType; diff --git a/tests/baselines/reference/mappedTypeTupleConstraintAssignability.symbols b/tests/baselines/reference/mappedTypeTupleConstraintAssignability.symbols new file mode 100644 index 0000000000000..c2bd5da2420ce --- /dev/null +++ b/tests/baselines/reference/mappedTypeTupleConstraintAssignability.symbols @@ -0,0 +1,134 @@ +=== tests/cases/compiler/mappedTypeTupleConstraintAssignability.ts === +// https://github.com/microsoft/TypeScript/issues/53359#issuecomment-1475390594 + +type Writeable = { -readonly [P in keyof T]: T[P] }; +>Writeable : Symbol(Writeable, Decl(mappedTypeTupleConstraintAssignability.ts, 0, 0)) +>T : Symbol(T, Decl(mappedTypeTupleConstraintAssignability.ts, 2, 15)) +>P : Symbol(P, Decl(mappedTypeTupleConstraintAssignability.ts, 2, 33)) +>T : Symbol(T, Decl(mappedTypeTupleConstraintAssignability.ts, 2, 15)) +>T : Symbol(T, Decl(mappedTypeTupleConstraintAssignability.ts, 2, 15)) +>P : Symbol(P, Decl(mappedTypeTupleConstraintAssignability.ts, 2, 33)) + +type EnumValues = [string, ...string[]]; +>EnumValues : Symbol(EnumValues, Decl(mappedTypeTupleConstraintAssignability.ts, 2, 55)) + +type Values = { [k in T[number]]: k; }; +>Values : Symbol(Values, Decl(mappedTypeTupleConstraintAssignability.ts, 3, 40)) +>T : Symbol(T, Decl(mappedTypeTupleConstraintAssignability.ts, 4, 12)) +>EnumValues : Symbol(EnumValues, Decl(mappedTypeTupleConstraintAssignability.ts, 2, 55)) +>k : Symbol(k, Decl(mappedTypeTupleConstraintAssignability.ts, 4, 39)) +>T : Symbol(T, Decl(mappedTypeTupleConstraintAssignability.ts, 4, 12)) +>k : Symbol(k, Decl(mappedTypeTupleConstraintAssignability.ts, 4, 39)) + +declare class ZodEnum { +>ZodEnum : Symbol(ZodEnum, Decl(mappedTypeTupleConstraintAssignability.ts, 4, 61)) +>T : Symbol(T, Decl(mappedTypeTupleConstraintAssignability.ts, 6, 22)) + + get enum(): Values +>enum : Symbol(ZodEnum.enum, Decl(mappedTypeTupleConstraintAssignability.ts, 6, 56)) +>Values : Symbol(Values, Decl(mappedTypeTupleConstraintAssignability.ts, 3, 40)) +>T : Symbol(T, Decl(mappedTypeTupleConstraintAssignability.ts, 6, 22)) +} + +declare function createZodEnum>(values: T): ZodEnum>; +>createZodEnum : Symbol(createZodEnum, Decl(mappedTypeTupleConstraintAssignability.ts, 8, 1)) +>U : Symbol(U, Decl(mappedTypeTupleConstraintAssignability.ts, 10, 31)) +>T : Symbol(T, Decl(mappedTypeTupleConstraintAssignability.ts, 10, 48)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>U : Symbol(U, Decl(mappedTypeTupleConstraintAssignability.ts, 10, 31)) +>U : Symbol(U, Decl(mappedTypeTupleConstraintAssignability.ts, 10, 31)) +>values : Symbol(values, Decl(mappedTypeTupleConstraintAssignability.ts, 10, 82)) +>T : Symbol(T, Decl(mappedTypeTupleConstraintAssignability.ts, 10, 48)) +>ZodEnum : Symbol(ZodEnum, Decl(mappedTypeTupleConstraintAssignability.ts, 4, 61)) +>Writeable : Symbol(Writeable, Decl(mappedTypeTupleConstraintAssignability.ts, 0, 0)) +>T : Symbol(T, Decl(mappedTypeTupleConstraintAssignability.ts, 10, 48)) + +// https://github.com/microsoft/TypeScript/issues/53359#issuecomment-1475390607 + +type Maybe = T | null | undefined; +>Maybe : Symbol(Maybe, Decl(mappedTypeTupleConstraintAssignability.ts, 10, 116)) +>T : Symbol(T, Decl(mappedTypeTupleConstraintAssignability.ts, 14, 11)) +>T : Symbol(T, Decl(mappedTypeTupleConstraintAssignability.ts, 14, 11)) + +type AnyTuple = [unknown, ...unknown[]]; +>AnyTuple : Symbol(AnyTuple, Decl(mappedTypeTupleConstraintAssignability.ts, 14, 37)) + +type AnyObject = { [k: string]: any }; +>AnyObject : Symbol(AnyObject, Decl(mappedTypeTupleConstraintAssignability.ts, 15, 40)) +>k : Symbol(k, Decl(mappedTypeTupleConstraintAssignability.ts, 16, 20)) + +type Flags = "s" | "d" | ""; +>Flags : Symbol(Flags, Decl(mappedTypeTupleConstraintAssignability.ts, 16, 38)) + +interface ISchema { +>ISchema : Symbol(ISchema, Decl(mappedTypeTupleConstraintAssignability.ts, 17, 28)) +>T : Symbol(T, Decl(mappedTypeTupleConstraintAssignability.ts, 19, 18)) +>C : Symbol(C, Decl(mappedTypeTupleConstraintAssignability.ts, 19, 20)) +>F : Symbol(F, Decl(mappedTypeTupleConstraintAssignability.ts, 19, 29)) +>Flags : Symbol(Flags, Decl(mappedTypeTupleConstraintAssignability.ts, 16, 38)) +>D : Symbol(D, Decl(mappedTypeTupleConstraintAssignability.ts, 19, 52)) + + __flags: F; +>__flags : Symbol(ISchema.__flags, Decl(mappedTypeTupleConstraintAssignability.ts, 19, 63)) +>F : Symbol(F, Decl(mappedTypeTupleConstraintAssignability.ts, 19, 29)) + + __context: C; +>__context : Symbol(ISchema.__context, Decl(mappedTypeTupleConstraintAssignability.ts, 20, 13)) +>C : Symbol(C, Decl(mappedTypeTupleConstraintAssignability.ts, 19, 20)) + + __outputType: T; +>__outputType : Symbol(ISchema.__outputType, Decl(mappedTypeTupleConstraintAssignability.ts, 21, 15)) +>T : Symbol(T, Decl(mappedTypeTupleConstraintAssignability.ts, 19, 18)) + + __default: D; +>__default : Symbol(ISchema.__default, Decl(mappedTypeTupleConstraintAssignability.ts, 22, 18)) +>D : Symbol(D, Decl(mappedTypeTupleConstraintAssignability.ts, 19, 52)) +} + +declare class TupleSchema< +>TupleSchema : Symbol(TupleSchema, Decl(mappedTypeTupleConstraintAssignability.ts, 24, 1)) + + TType extends Maybe = AnyTuple | undefined, +>TType : Symbol(TType, Decl(mappedTypeTupleConstraintAssignability.ts, 26, 26)) +>Maybe : Symbol(Maybe, Decl(mappedTypeTupleConstraintAssignability.ts, 10, 116)) +>AnyTuple : Symbol(AnyTuple, Decl(mappedTypeTupleConstraintAssignability.ts, 14, 37)) +>AnyTuple : Symbol(AnyTuple, Decl(mappedTypeTupleConstraintAssignability.ts, 14, 37)) + + TContext = AnyObject, +>TContext : Symbol(TContext, Decl(mappedTypeTupleConstraintAssignability.ts, 27, 55)) +>AnyObject : Symbol(AnyObject, Decl(mappedTypeTupleConstraintAssignability.ts, 15, 40)) + + TDefault = undefined, +>TDefault : Symbol(TDefault, Decl(mappedTypeTupleConstraintAssignability.ts, 28, 23)) + + TFlags extends Flags = "" +>TFlags : Symbol(TFlags, Decl(mappedTypeTupleConstraintAssignability.ts, 29, 23)) +>Flags : Symbol(Flags, Decl(mappedTypeTupleConstraintAssignability.ts, 16, 38)) + +> { + constructor(schemas: [ISchema, ...ISchema[]]); +>schemas : Symbol(schemas, Decl(mappedTypeTupleConstraintAssignability.ts, 32, 14)) +>ISchema : Symbol(ISchema, Decl(mappedTypeTupleConstraintAssignability.ts, 17, 28)) +>ISchema : Symbol(ISchema, Decl(mappedTypeTupleConstraintAssignability.ts, 17, 28)) +} + +export function create(schemas: { +>create : Symbol(create, Decl(mappedTypeTupleConstraintAssignability.ts, 33, 1)) +>T : Symbol(T, Decl(mappedTypeTupleConstraintAssignability.ts, 35, 23)) +>AnyTuple : Symbol(AnyTuple, Decl(mappedTypeTupleConstraintAssignability.ts, 14, 37)) +>schemas : Symbol(schemas, Decl(mappedTypeTupleConstraintAssignability.ts, 35, 43)) + + [K in keyof T]: ISchema; +>K : Symbol(K, Decl(mappedTypeTupleConstraintAssignability.ts, 36, 3)) +>T : Symbol(T, Decl(mappedTypeTupleConstraintAssignability.ts, 35, 23)) +>ISchema : Symbol(ISchema, Decl(mappedTypeTupleConstraintAssignability.ts, 17, 28)) +>T : Symbol(T, Decl(mappedTypeTupleConstraintAssignability.ts, 35, 23)) +>K : Symbol(K, Decl(mappedTypeTupleConstraintAssignability.ts, 36, 3)) + +}) { + return new TupleSchema(schemas); +>TupleSchema : Symbol(TupleSchema, Decl(mappedTypeTupleConstraintAssignability.ts, 24, 1)) +>T : Symbol(T, Decl(mappedTypeTupleConstraintAssignability.ts, 35, 23)) +>schemas : Symbol(schemas, Decl(mappedTypeTupleConstraintAssignability.ts, 35, 43)) +} + diff --git a/tests/baselines/reference/mappedTypeTupleConstraintAssignability.types b/tests/baselines/reference/mappedTypeTupleConstraintAssignability.types new file mode 100644 index 0000000000000..ae3c60e654a04 --- /dev/null +++ b/tests/baselines/reference/mappedTypeTupleConstraintAssignability.types @@ -0,0 +1,76 @@ +=== tests/cases/compiler/mappedTypeTupleConstraintAssignability.ts === +// https://github.com/microsoft/TypeScript/issues/53359#issuecomment-1475390594 + +type Writeable = { -readonly [P in keyof T]: T[P] }; +>Writeable : Writeable + +type EnumValues = [string, ...string[]]; +>EnumValues : [string, ...string[]] + +type Values = { [k in T[number]]: k; }; +>Values : Values + +declare class ZodEnum { +>ZodEnum : ZodEnum + + get enum(): Values +>enum : Values +} + +declare function createZodEnum>(values: T): ZodEnum>; +>createZodEnum : (values: T) => ZodEnum> +>values : T + +// https://github.com/microsoft/TypeScript/issues/53359#issuecomment-1475390607 + +type Maybe = T | null | undefined; +>Maybe : Maybe + +type AnyTuple = [unknown, ...unknown[]]; +>AnyTuple : [unknown, ...unknown[]] + +type AnyObject = { [k: string]: any }; +>AnyObject : { [k: string]: any; } +>k : string + +type Flags = "s" | "d" | ""; +>Flags : "" | "s" | "d" + +interface ISchema { + __flags: F; +>__flags : F + + __context: C; +>__context : C + + __outputType: T; +>__outputType : T + + __default: D; +>__default : D +} + +declare class TupleSchema< +>TupleSchema : TupleSchema + + TType extends Maybe = AnyTuple | undefined, + TContext = AnyObject, + TDefault = undefined, + TFlags extends Flags = "" +> { + constructor(schemas: [ISchema, ...ISchema[]]); +>schemas : [ISchema, ...ISchema[]] +} + +export function create(schemas: { +>create : (schemas: { [K in keyof T]: ISchema; }) => TupleSchema +>schemas : { [K in keyof T]: ISchema; } + + [K in keyof T]: ISchema; +}) { + return new TupleSchema(schemas); +>new TupleSchema(schemas) : TupleSchema +>TupleSchema : typeof TupleSchema +>schemas : { [K in keyof T]: ISchema; } +} + diff --git a/tests/baselines/reference/mappedTypeUnionConstrainTupleTreatedAsArrayLike.errors.txt b/tests/baselines/reference/mappedTypeUnionConstrainTupleTreatedAsArrayLike.errors.txt new file mode 100644 index 0000000000000..177f381f11906 --- /dev/null +++ b/tests/baselines/reference/mappedTypeUnionConstrainTupleTreatedAsArrayLike.errors.txt @@ -0,0 +1,18 @@ +tests/cases/compiler/mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts(9,9): error TS2322: Type 'HomomorphicMappedType' is not assignable to type 'any[]'. + + +==== tests/cases/compiler/mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts (1 errors) ==== + type HomomorphicMappedType = { [P in keyof T]: T[P] extends string ? boolean : null } + + function test1(args: T) { + const arr: any[] = [] as HomomorphicMappedType + const arr2: readonly any[] = [] as HomomorphicMappedType + } + + function test2(args: T) { + const arr: any[] = [] as HomomorphicMappedType // error + ~~~ +!!! error TS2322: Type 'HomomorphicMappedType' is not assignable to type 'any[]'. + const arr2: readonly any[] = [] as HomomorphicMappedType + } + \ No newline at end of file diff --git a/tests/baselines/reference/mappedTypeUnionConstrainTupleTreatedAsArrayLike.symbols b/tests/baselines/reference/mappedTypeUnionConstrainTupleTreatedAsArrayLike.symbols new file mode 100644 index 0000000000000..73af8f8dd924a --- /dev/null +++ b/tests/baselines/reference/mappedTypeUnionConstrainTupleTreatedAsArrayLike.symbols @@ -0,0 +1,43 @@ +=== tests/cases/compiler/mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts === +type HomomorphicMappedType = { [P in keyof T]: T[P] extends string ? boolean : null } +>HomomorphicMappedType : Symbol(HomomorphicMappedType, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 0, 0)) +>T : Symbol(T, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 0, 27)) +>P : Symbol(P, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 0, 35)) +>T : Symbol(T, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 0, 27)) +>T : Symbol(T, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 0, 27)) +>P : Symbol(P, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 0, 35)) + +function test1(args: T) { +>test1 : Symbol(test1, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 0, 88)) +>T : Symbol(T, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 2, 15)) +>args : Symbol(args, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 2, 46)) +>T : Symbol(T, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 2, 15)) + + const arr: any[] = [] as HomomorphicMappedType +>arr : Symbol(arr, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 3, 7)) +>HomomorphicMappedType : Symbol(HomomorphicMappedType, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 0, 0)) +>T : Symbol(T, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 2, 15)) + + const arr2: readonly any[] = [] as HomomorphicMappedType +>arr2 : Symbol(arr2, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 4, 7)) +>HomomorphicMappedType : Symbol(HomomorphicMappedType, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 0, 0)) +>T : Symbol(T, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 2, 15)) +} + +function test2(args: T) { +>test2 : Symbol(test2, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 5, 1)) +>T : Symbol(T, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 7, 15)) +>args : Symbol(args, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 7, 55)) +>T : Symbol(T, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 7, 15)) + + const arr: any[] = [] as HomomorphicMappedType // error +>arr : Symbol(arr, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 8, 7)) +>HomomorphicMappedType : Symbol(HomomorphicMappedType, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 0, 0)) +>T : Symbol(T, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 7, 15)) + + const arr2: readonly any[] = [] as HomomorphicMappedType +>arr2 : Symbol(arr2, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 9, 7)) +>HomomorphicMappedType : Symbol(HomomorphicMappedType, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 0, 0)) +>T : Symbol(T, Decl(mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts, 7, 15)) +} + diff --git a/tests/baselines/reference/mappedTypeUnionConstrainTupleTreatedAsArrayLike.types b/tests/baselines/reference/mappedTypeUnionConstrainTupleTreatedAsArrayLike.types new file mode 100644 index 0000000000000..cb1afa4b87d80 --- /dev/null +++ b/tests/baselines/reference/mappedTypeUnionConstrainTupleTreatedAsArrayLike.types @@ -0,0 +1,34 @@ +=== tests/cases/compiler/mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts === +type HomomorphicMappedType = { [P in keyof T]: T[P] extends string ? boolean : null } +>HomomorphicMappedType : HomomorphicMappedType + +function test1(args: T) { +>test1 : (args: T) => void +>args : T + + const arr: any[] = [] as HomomorphicMappedType +>arr : any[] +>[] as HomomorphicMappedType : HomomorphicMappedType +>[] : [] + + const arr2: readonly any[] = [] as HomomorphicMappedType +>arr2 : readonly any[] +>[] as HomomorphicMappedType : HomomorphicMappedType +>[] : [] +} + +function test2(args: T) { +>test2 : (args: T) => void +>args : T + + const arr: any[] = [] as HomomorphicMappedType // error +>arr : any[] +>[] as HomomorphicMappedType : HomomorphicMappedType +>[] : [] + + const arr2: readonly any[] = [] as HomomorphicMappedType +>arr2 : readonly any[] +>[] as HomomorphicMappedType : HomomorphicMappedType +>[] : [] +} + diff --git a/tests/baselines/reference/restParamUsingMappedTypeOverUnionConstraint.symbols b/tests/baselines/reference/restParamUsingMappedTypeOverUnionConstraint.symbols new file mode 100644 index 0000000000000..1fa2ee66c7789 --- /dev/null +++ b/tests/baselines/reference/restParamUsingMappedTypeOverUnionConstraint.symbols @@ -0,0 +1,27 @@ +=== tests/cases/compiler/restParamUsingMappedTypeOverUnionConstraint.ts === +// repro 29919#issuecomment-470948453 + +type HomomorphicMappedType = { [P in keyof T]: T[P] extends string ? boolean : null } +>HomomorphicMappedType : Symbol(HomomorphicMappedType, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 0, 0)) +>T : Symbol(T, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 2, 27)) +>P : Symbol(P, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 2, 35)) +>T : Symbol(T, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 2, 27)) +>T : Symbol(T, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 2, 27)) +>P : Symbol(P, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 2, 35)) + +declare function test( +>test : Symbol(test, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 2, 88)) +>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: HomomorphicMappedType) => void +>fn : Symbol(fn, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 5, 10)) +>args : Symbol(args, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 6, 7)) +>HomomorphicMappedType : Symbol(HomomorphicMappedType, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 0, 0)) +>T : Symbol(T, Decl(restParamUsingMappedTypeOverUnionConstraint.ts, 4, 22)) + +): void + diff --git a/tests/baselines/reference/restParamUsingMappedTypeOverUnionConstraint.types b/tests/baselines/reference/restParamUsingMappedTypeOverUnionConstraint.types new file mode 100644 index 0000000000000..8630f15deb77a --- /dev/null +++ b/tests/baselines/reference/restParamUsingMappedTypeOverUnionConstraint.types @@ -0,0 +1,18 @@ +=== tests/cases/compiler/restParamUsingMappedTypeOverUnionConstraint.ts === +// repro 29919#issuecomment-470948453 + +type HomomorphicMappedType = { [P in keyof T]: T[P] extends string ? boolean : null } +>HomomorphicMappedType : HomomorphicMappedType + +declare function test( +>test : (args: T, fn: (...args: HomomorphicMappedType) => void) => void + + args: T, +>args : T + + fn: (...args: HomomorphicMappedType) => void +>fn : (...args: HomomorphicMappedType) => void +>args : HomomorphicMappedType + +): void + diff --git a/tests/cases/compiler/mappedTypeTupleConstraintAssignability.ts b/tests/cases/compiler/mappedTypeTupleConstraintAssignability.ts new file mode 100644 index 0000000000000..b99300c909d9c --- /dev/null +++ b/tests/cases/compiler/mappedTypeTupleConstraintAssignability.ts @@ -0,0 +1,43 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/53359#issuecomment-1475390594 + +type Writeable = { -readonly [P in keyof T]: T[P] }; +type EnumValues = [string, ...string[]]; +type Values = { [k in T[number]]: k; }; + +declare class ZodEnum { + get enum(): Values +} + +declare function createZodEnum>(values: T): ZodEnum>; + +// https://github.com/microsoft/TypeScript/issues/53359#issuecomment-1475390607 + +type Maybe = T | null | undefined; +type AnyTuple = [unknown, ...unknown[]]; +type AnyObject = { [k: string]: any }; +type Flags = "s" | "d" | ""; + +interface ISchema { + __flags: F; + __context: C; + __outputType: T; + __default: D; +} + +declare class TupleSchema< + TType extends Maybe = AnyTuple | undefined, + TContext = AnyObject, + TDefault = undefined, + TFlags extends Flags = "" +> { + constructor(schemas: [ISchema, ...ISchema[]]); +} + +export function create(schemas: { + [K in keyof T]: ISchema; +}) { + return new TupleSchema(schemas); +} diff --git a/tests/cases/compiler/mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts b/tests/cases/compiler/mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts new file mode 100644 index 0000000000000..51e30a9fdc45b --- /dev/null +++ b/tests/cases/compiler/mappedTypeUnionConstrainTupleTreatedAsArrayLike.ts @@ -0,0 +1,14 @@ +// @noEmit: true +// @strict: true + +type HomomorphicMappedType = { [P in keyof T]: T[P] extends string ? boolean : null } + +function test1(args: T) { + const arr: any[] = [] as HomomorphicMappedType + const arr2: readonly any[] = [] as HomomorphicMappedType +} + +function test2(args: T) { + const arr: any[] = [] as HomomorphicMappedType // error + const arr2: readonly any[] = [] as HomomorphicMappedType +} diff --git a/tests/cases/compiler/restParamUsingMappedTypeOverUnionConstraint.ts b/tests/cases/compiler/restParamUsingMappedTypeOverUnionConstraint.ts new file mode 100644 index 0000000000000..c58b0278511fc --- /dev/null +++ b/tests/cases/compiler/restParamUsingMappedTypeOverUnionConstraint.ts @@ -0,0 +1,11 @@ +// @noEmit: true +// @strict: true + +// repro 29919#issuecomment-470948453 + +type HomomorphicMappedType = { [P in keyof T]: T[P] extends string ? boolean : null } + +declare function test( + args: T, + fn: (...args: HomomorphicMappedType) => void +): void