mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
Fixed const reverse mapped types themselves to be treated as const (#55794)
This commit is contained in:
parent
2d4cacdf39
commit
c474123b47
@ -14055,6 +14055,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return hasNonCircularBaseConstraint(typeParameter) ? getConstraintFromTypeParameter(typeParameter) : undefined;
|
||||
}
|
||||
|
||||
function isConstMappedType(type: MappedType, depth: number): boolean {
|
||||
const typeVariable = getHomomorphicTypeVariable(type);
|
||||
return !!typeVariable && isConstTypeVariable(typeVariable, depth);
|
||||
}
|
||||
|
||||
function isConstTypeVariable(type: Type | undefined, depth = 0): boolean {
|
||||
return depth < 5 && !!(type && (
|
||||
type.flags & TypeFlags.TypeParameter && some((type as TypeParameter).symbol?.declarations, d => hasSyntacticModifier(d, ModifierFlags.Const)) ||
|
||||
@ -14062,6 +14067,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
type.flags & TypeFlags.IndexedAccess && isConstTypeVariable((type as IndexedAccessType).objectType, depth + 1) ||
|
||||
type.flags & TypeFlags.Conditional && isConstTypeVariable(getConstraintOfConditionalType(type as ConditionalType), depth + 1) ||
|
||||
type.flags & TypeFlags.Substitution && isConstTypeVariable((type as SubstitutionType).baseType, depth) ||
|
||||
getObjectFlags(type) & ObjectFlags.Mapped && isConstMappedType(type as MappedType, depth) ||
|
||||
isGenericTupleType(type) && findIndex(getElementTypes(type), (t, i) => !!(type.target.elementFlags[i] & ElementFlags.Variadic) && isConstTypeVariable(t, depth)) >= 0
|
||||
));
|
||||
}
|
||||
|
||||
@ -402,8 +402,8 @@ const thingMapped = <const O extends Record<string, any>>(o: NotEmptyMapped<O>)
|
||||
>o : NotEmptyMapped<O>
|
||||
|
||||
const tMapped = thingMapped({ foo: '' }); // { foo: "" }
|
||||
>tMapped : { foo: ""; }
|
||||
>thingMapped({ foo: '' }) : { foo: ""; }
|
||||
>tMapped : { readonly foo: ""; }
|
||||
>thingMapped({ foo: '' }) : { readonly foo: ""; }
|
||||
>thingMapped : <const O extends Record<string, any>>(o: NotEmptyMapped<O>) => NotEmptyMapped<O>
|
||||
>{ foo: '' } : { foo: ""; }
|
||||
>foo : ""
|
||||
|
||||
@ -0,0 +1,135 @@
|
||||
//// [tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiersReverseMappedTypes.ts] ////
|
||||
|
||||
=== typeParameterConstModifiersReverseMappedTypes.ts ===
|
||||
declare function test1<const T>(obj: {
|
||||
>test1 : Symbol(test1, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 0, 23))
|
||||
>obj : Symbol(obj, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 0, 32))
|
||||
|
||||
[K in keyof T]: T[K];
|
||||
>K : Symbol(K, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 1, 3))
|
||||
>T : Symbol(T, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 0, 23))
|
||||
>T : Symbol(T, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 0, 23))
|
||||
>K : Symbol(K, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 1, 3))
|
||||
|
||||
}): [T, typeof obj];
|
||||
>T : Symbol(T, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 0, 23))
|
||||
>obj : Symbol(obj, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 0, 32))
|
||||
|
||||
const result1 = test1({
|
||||
>result1 : Symbol(result1, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 4, 5))
|
||||
>test1 : Symbol(test1, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 0, 0))
|
||||
|
||||
prop: "foo",
|
||||
>prop : Symbol(prop, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 4, 23))
|
||||
|
||||
nested: {
|
||||
>nested : Symbol(nested, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 5, 14))
|
||||
|
||||
nestedProp: "bar",
|
||||
>nestedProp : Symbol(nestedProp, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 6, 11))
|
||||
|
||||
},
|
||||
});
|
||||
|
||||
declare function test2<const T>(obj: {
|
||||
>test2 : Symbol(test2, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 9, 3))
|
||||
>T : Symbol(T, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 11, 23))
|
||||
>obj : Symbol(obj, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 11, 32))
|
||||
|
||||
readonly [K in keyof T]: T[K];
|
||||
>K : Symbol(K, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 12, 12))
|
||||
>T : Symbol(T, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 11, 23))
|
||||
>T : Symbol(T, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 11, 23))
|
||||
>K : Symbol(K, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 12, 12))
|
||||
|
||||
}): [T, typeof obj];
|
||||
>T : Symbol(T, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 11, 23))
|
||||
>obj : Symbol(obj, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 11, 32))
|
||||
|
||||
const result2 = test2({
|
||||
>result2 : Symbol(result2, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 15, 5))
|
||||
>test2 : Symbol(test2, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 9, 3))
|
||||
|
||||
prop: "foo",
|
||||
>prop : Symbol(prop, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 15, 23))
|
||||
|
||||
nested: {
|
||||
>nested : Symbol(nested, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 16, 14))
|
||||
|
||||
nestedProp: "bar",
|
||||
>nestedProp : Symbol(nestedProp, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 17, 11))
|
||||
|
||||
},
|
||||
});
|
||||
|
||||
declare function test3<const T>(obj: {
|
||||
>test3 : Symbol(test3, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 20, 3))
|
||||
>T : Symbol(T, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 22, 23))
|
||||
>obj : Symbol(obj, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 22, 32))
|
||||
|
||||
-readonly [K in keyof T]: T[K];
|
||||
>K : Symbol(K, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 23, 13))
|
||||
>T : Symbol(T, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 22, 23))
|
||||
>T : Symbol(T, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 22, 23))
|
||||
>K : Symbol(K, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 23, 13))
|
||||
|
||||
}): [T, typeof obj];
|
||||
>T : Symbol(T, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 22, 23))
|
||||
>obj : Symbol(obj, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 22, 32))
|
||||
|
||||
const result3 = test3({
|
||||
>result3 : Symbol(result3, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 26, 5))
|
||||
>test3 : Symbol(test3, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 20, 3))
|
||||
|
||||
prop: "foo",
|
||||
>prop : Symbol(prop, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 26, 23))
|
||||
|
||||
nested: {
|
||||
>nested : Symbol(nested, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 27, 14))
|
||||
|
||||
nestedProp: "bar",
|
||||
>nestedProp : Symbol(nestedProp, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 28, 11))
|
||||
|
||||
},
|
||||
});
|
||||
|
||||
declare function test4<const T extends readonly unknown[]>(arr: {
|
||||
>test4 : Symbol(test4, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 31, 3))
|
||||
>T : Symbol(T, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 33, 23))
|
||||
>arr : Symbol(arr, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 33, 59))
|
||||
|
||||
[K in keyof T]: T[K];
|
||||
>K : Symbol(K, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 34, 3))
|
||||
>T : Symbol(T, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 33, 23))
|
||||
>T : Symbol(T, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 33, 23))
|
||||
>K : Symbol(K, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 34, 3))
|
||||
|
||||
}): T;
|
||||
>T : Symbol(T, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 33, 23))
|
||||
|
||||
const result4 = test4(["1", 2]);
|
||||
>result4 : Symbol(result4, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 37, 5))
|
||||
>test4 : Symbol(test4, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 31, 3))
|
||||
|
||||
declare function test5<const T extends readonly unknown[]>(
|
||||
>test5 : Symbol(test5, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 37, 32))
|
||||
>T : Symbol(T, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 39, 23))
|
||||
|
||||
...args: {
|
||||
>args : Symbol(args, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 39, 59))
|
||||
|
||||
[K in keyof T]: T[K];
|
||||
>K : Symbol(K, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 41, 5))
|
||||
>T : Symbol(T, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 39, 23))
|
||||
>T : Symbol(T, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 39, 23))
|
||||
>K : Symbol(K, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 41, 5))
|
||||
}
|
||||
): T;
|
||||
>T : Symbol(T, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 39, 23))
|
||||
|
||||
const result5 = test5({ a: "foo" });
|
||||
>result5 : Symbol(result5, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 45, 5))
|
||||
>test5 : Symbol(test5, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 37, 32))
|
||||
>a : Symbol(a, Decl(typeParameterConstModifiersReverseMappedTypes.ts, 45, 23))
|
||||
|
||||
@ -0,0 +1,123 @@
|
||||
//// [tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiersReverseMappedTypes.ts] ////
|
||||
|
||||
=== typeParameterConstModifiersReverseMappedTypes.ts ===
|
||||
declare function test1<const T>(obj: {
|
||||
>test1 : <const T>(obj: { [K in keyof T]: T[K]; }) => [T, typeof obj]
|
||||
>obj : { [K in keyof T]: T[K]; }
|
||||
|
||||
[K in keyof T]: T[K];
|
||||
}): [T, typeof obj];
|
||||
>obj : { [K in keyof T]: T[K]; }
|
||||
|
||||
const result1 = test1({
|
||||
>result1 : [{ readonly prop: "foo"; readonly nested: { readonly nestedProp: "bar"; }; }, { readonly prop: "foo"; readonly nested: { readonly nestedProp: "bar"; }; }]
|
||||
>test1({ prop: "foo", nested: { nestedProp: "bar", },}) : [{ readonly prop: "foo"; readonly nested: { readonly nestedProp: "bar"; }; }, { readonly prop: "foo"; readonly nested: { readonly nestedProp: "bar"; }; }]
|
||||
>test1 : <const T>(obj: { [K in keyof T]: T[K]; }) => [T, { [K in keyof T]: T[K]; }]
|
||||
>{ prop: "foo", nested: { nestedProp: "bar", },} : { prop: "foo"; nested: { nestedProp: "bar"; }; }
|
||||
|
||||
prop: "foo",
|
||||
>prop : "foo"
|
||||
>"foo" : "foo"
|
||||
|
||||
nested: {
|
||||
>nested : { nestedProp: "bar"; }
|
||||
>{ nestedProp: "bar", } : { nestedProp: "bar"; }
|
||||
|
||||
nestedProp: "bar",
|
||||
>nestedProp : "bar"
|
||||
>"bar" : "bar"
|
||||
|
||||
},
|
||||
});
|
||||
|
||||
declare function test2<const T>(obj: {
|
||||
>test2 : <const T>(obj: { readonly [K in keyof T]: T[K]; }) => [T, typeof obj]
|
||||
>obj : { readonly [K in keyof T]: T[K]; }
|
||||
|
||||
readonly [K in keyof T]: T[K];
|
||||
}): [T, typeof obj];
|
||||
>obj : { readonly [K in keyof T]: T[K]; }
|
||||
|
||||
const result2 = test2({
|
||||
>result2 : [{ prop: "foo"; nested: { readonly nestedProp: "bar"; }; }, { readonly prop: "foo"; readonly nested: { readonly nestedProp: "bar"; }; }]
|
||||
>test2({ prop: "foo", nested: { nestedProp: "bar", },}) : [{ prop: "foo"; nested: { readonly nestedProp: "bar"; }; }, { readonly prop: "foo"; readonly nested: { readonly nestedProp: "bar"; }; }]
|
||||
>test2 : <const T>(obj: { readonly [K in keyof T]: T[K]; }) => [T, { readonly [K in keyof T]: T[K]; }]
|
||||
>{ prop: "foo", nested: { nestedProp: "bar", },} : { prop: "foo"; nested: { nestedProp: "bar"; }; }
|
||||
|
||||
prop: "foo",
|
||||
>prop : "foo"
|
||||
>"foo" : "foo"
|
||||
|
||||
nested: {
|
||||
>nested : { nestedProp: "bar"; }
|
||||
>{ nestedProp: "bar", } : { nestedProp: "bar"; }
|
||||
|
||||
nestedProp: "bar",
|
||||
>nestedProp : "bar"
|
||||
>"bar" : "bar"
|
||||
|
||||
},
|
||||
});
|
||||
|
||||
declare function test3<const T>(obj: {
|
||||
>test3 : <const T>(obj: { -readonly [K in keyof T]: T[K]; }) => [T, typeof obj]
|
||||
>obj : { -readonly [K in keyof T]: T[K]; }
|
||||
|
||||
-readonly [K in keyof T]: T[K];
|
||||
}): [T, typeof obj];
|
||||
>obj : { -readonly [K in keyof T]: T[K]; }
|
||||
|
||||
const result3 = test3({
|
||||
>result3 : [{ readonly prop: "foo"; readonly nested: { readonly nestedProp: "bar"; }; }, { prop: "foo"; nested: { readonly nestedProp: "bar"; }; }]
|
||||
>test3({ prop: "foo", nested: { nestedProp: "bar", },}) : [{ readonly prop: "foo"; readonly nested: { readonly nestedProp: "bar"; }; }, { prop: "foo"; nested: { readonly nestedProp: "bar"; }; }]
|
||||
>test3 : <const T>(obj: { -readonly [K in keyof T]: T[K]; }) => [T, { -readonly [K in keyof T]: T[K]; }]
|
||||
>{ prop: "foo", nested: { nestedProp: "bar", },} : { prop: "foo"; nested: { nestedProp: "bar"; }; }
|
||||
|
||||
prop: "foo",
|
||||
>prop : "foo"
|
||||
>"foo" : "foo"
|
||||
|
||||
nested: {
|
||||
>nested : { nestedProp: "bar"; }
|
||||
>{ nestedProp: "bar", } : { nestedProp: "bar"; }
|
||||
|
||||
nestedProp: "bar",
|
||||
>nestedProp : "bar"
|
||||
>"bar" : "bar"
|
||||
|
||||
},
|
||||
});
|
||||
|
||||
declare function test4<const T extends readonly unknown[]>(arr: {
|
||||
>test4 : <const T extends readonly unknown[]>(arr: { [K in keyof T]: T[K]; }) => T
|
||||
>arr : { [K in keyof T]: T[K]; }
|
||||
|
||||
[K in keyof T]: T[K];
|
||||
}): T;
|
||||
|
||||
const result4 = test4(["1", 2]);
|
||||
>result4 : readonly ["1", 2]
|
||||
>test4(["1", 2]) : readonly ["1", 2]
|
||||
>test4 : <const T extends readonly unknown[]>(arr: { [K in keyof T]: T[K]; }) => T
|
||||
>["1", 2] : ["1", 2]
|
||||
>"1" : "1"
|
||||
>2 : 2
|
||||
|
||||
declare function test5<const T extends readonly unknown[]>(
|
||||
>test5 : <const T extends readonly unknown[]>(...args: { [K in keyof T]: T[K]; }) => T
|
||||
|
||||
...args: {
|
||||
>args : { [K in keyof T]: T[K]; }
|
||||
|
||||
[K in keyof T]: T[K];
|
||||
}
|
||||
): T;
|
||||
|
||||
const result5 = test5({ a: "foo" });
|
||||
>result5 : readonly [{ readonly a: "foo"; }]
|
||||
>test5({ a: "foo" }) : readonly [{ readonly a: "foo"; }]
|
||||
>test5 : <const T extends readonly unknown[]>(...args: { [K in keyof T]: T[K]; }) => T
|
||||
>{ a: "foo" } : { a: "foo"; }
|
||||
>a : "foo"
|
||||
>"foo" : "foo"
|
||||
|
||||
@ -0,0 +1,49 @@
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
|
||||
declare function test1<const T>(obj: {
|
||||
[K in keyof T]: T[K];
|
||||
}): [T, typeof obj];
|
||||
|
||||
const result1 = test1({
|
||||
prop: "foo",
|
||||
nested: {
|
||||
nestedProp: "bar",
|
||||
},
|
||||
});
|
||||
|
||||
declare function test2<const T>(obj: {
|
||||
readonly [K in keyof T]: T[K];
|
||||
}): [T, typeof obj];
|
||||
|
||||
const result2 = test2({
|
||||
prop: "foo",
|
||||
nested: {
|
||||
nestedProp: "bar",
|
||||
},
|
||||
});
|
||||
|
||||
declare function test3<const T>(obj: {
|
||||
-readonly [K in keyof T]: T[K];
|
||||
}): [T, typeof obj];
|
||||
|
||||
const result3 = test3({
|
||||
prop: "foo",
|
||||
nested: {
|
||||
nestedProp: "bar",
|
||||
},
|
||||
});
|
||||
|
||||
declare function test4<const T extends readonly unknown[]>(arr: {
|
||||
[K in keyof T]: T[K];
|
||||
}): T;
|
||||
|
||||
const result4 = test4(["1", 2]);
|
||||
|
||||
declare function test5<const T extends readonly unknown[]>(
|
||||
...args: {
|
||||
[K in keyof T]: T[K];
|
||||
}
|
||||
): T;
|
||||
|
||||
const result5 = test5({ a: "foo" });
|
||||
Loading…
x
Reference in New Issue
Block a user