Use const context in intersections containing const type variables (#55779)

This commit is contained in:
Mateusz Burzyński 2023-09-19 23:26:14 +02:00 committed by GitHub
parent 79736eff89
commit 6e01b06616
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 132 additions and 1 deletions

View File

@ -13912,7 +13912,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
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)) ||
type.flags & TypeFlags.Union && some((type as UnionType).types, t => isConstTypeVariable(t, depth)) ||
type.flags & TypeFlags.UnionOrIntersection && some((type as UnionOrIntersectionType).types, t => isConstTypeVariable(t, depth)) ||
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) ||

View File

@ -0,0 +1,56 @@
//// [tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiersWithIntersection.ts] ////
=== typeParameterConstModifiersWithIntersection.ts ===
// https://github.com/microsoft/TypeScript/issues/55778
interface Config<T1 extends { type: string }> {
>Config : Symbol(Config, Decl(typeParameterConstModifiersWithIntersection.ts, 0, 0))
>T1 : Symbol(T1, Decl(typeParameterConstModifiersWithIntersection.ts, 2, 17))
>type : Symbol(type, Decl(typeParameterConstModifiersWithIntersection.ts, 2, 29))
useIt: T1;
>useIt : Symbol(Config.useIt, Decl(typeParameterConstModifiersWithIntersection.ts, 2, 47))
>T1 : Symbol(T1, Decl(typeParameterConstModifiersWithIntersection.ts, 2, 17))
}
declare function test<
>test : Symbol(test, Decl(typeParameterConstModifiersWithIntersection.ts, 4, 1))
T1 extends { type: string },
>T1 : Symbol(T1, Decl(typeParameterConstModifiersWithIntersection.ts, 6, 22))
>type : Symbol(type, Decl(typeParameterConstModifiersWithIntersection.ts, 7, 14))
const TConfig extends Config<T1>,
>TConfig : Symbol(TConfig, Decl(typeParameterConstModifiersWithIntersection.ts, 7, 30))
>Config : Symbol(Config, Decl(typeParameterConstModifiersWithIntersection.ts, 0, 0))
>T1 : Symbol(T1, Decl(typeParameterConstModifiersWithIntersection.ts, 6, 22))
>(config: { produceThing: T1 } & TConfig): TConfig;
>config : Symbol(config, Decl(typeParameterConstModifiersWithIntersection.ts, 9, 2))
>produceThing : Symbol(produceThing, Decl(typeParameterConstModifiersWithIntersection.ts, 9, 11))
>T1 : Symbol(T1, Decl(typeParameterConstModifiersWithIntersection.ts, 6, 22))
>TConfig : Symbol(TConfig, Decl(typeParameterConstModifiersWithIntersection.ts, 7, 30))
>TConfig : Symbol(TConfig, Decl(typeParameterConstModifiersWithIntersection.ts, 7, 30))
const result = test({
>result : Symbol(result, Decl(typeParameterConstModifiersWithIntersection.ts, 11, 5))
>test : Symbol(test, Decl(typeParameterConstModifiersWithIntersection.ts, 4, 1))
produceThing: {} as {
>produceThing : Symbol(produceThing, Decl(typeParameterConstModifiersWithIntersection.ts, 11, 21))
type: "foo";
>type : Symbol(type, Decl(typeParameterConstModifiersWithIntersection.ts, 12, 23))
},
useIt: {
>useIt : Symbol(useIt, Decl(typeParameterConstModifiersWithIntersection.ts, 14, 4))
type: "foo",
>type : Symbol(type, Decl(typeParameterConstModifiersWithIntersection.ts, 15, 10))
},
extra: 10,
>extra : Symbol(extra, Decl(typeParameterConstModifiersWithIntersection.ts, 17, 4))
});

View File

@ -0,0 +1,52 @@
//// [tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiersWithIntersection.ts] ////
=== typeParameterConstModifiersWithIntersection.ts ===
// https://github.com/microsoft/TypeScript/issues/55778
interface Config<T1 extends { type: string }> {
>type : string
useIt: T1;
>useIt : T1
}
declare function test<
>test : <T1 extends { type: string; }, const TConfig extends Config<T1>>(config: { produceThing: T1;} & TConfig) => TConfig
T1 extends { type: string },
>type : string
const TConfig extends Config<T1>,
>(config: { produceThing: T1 } & TConfig): TConfig;
>config : { produceThing: T1; } & TConfig
>produceThing : T1
const result = test({
>result : { readonly produceThing: { type: "foo"; }; readonly useIt: { readonly type: "foo"; }; readonly extra: 10; }
>test({ produceThing: {} as { type: "foo"; }, useIt: { type: "foo", }, extra: 10,}) : { readonly produceThing: { type: "foo"; }; readonly useIt: { readonly type: "foo"; }; readonly extra: 10; }
>test : <T1 extends { type: string; }, const TConfig extends Config<T1>>(config: { produceThing: T1; } & TConfig) => TConfig
>{ produceThing: {} as { type: "foo"; }, useIt: { type: "foo", }, extra: 10,} : { produceThing: { type: "foo"; }; useIt: { type: "foo"; }; extra: 10; }
produceThing: {} as {
>produceThing : { type: "foo"; }
>{} as { type: "foo"; } : { type: "foo"; }
>{} : {}
type: "foo";
>type : "foo"
},
useIt: {
>useIt : { type: "foo"; }
>{ type: "foo", } : { type: "foo"; }
type: "foo",
>type : "foo"
>"foo" : "foo"
},
extra: 10,
>extra : 10
>10 : 10
});

View File

@ -0,0 +1,23 @@
// @strict: true
// @noEmit: true
// https://github.com/microsoft/TypeScript/issues/55778
interface Config<T1 extends { type: string }> {
useIt: T1;
}
declare function test<
T1 extends { type: string },
const TConfig extends Config<T1>,
>(config: { produceThing: T1 } & TConfig): TConfig;
const result = test({
produceThing: {} as {
type: "foo";
},
useIt: {
type: "foo",
},
extra: 10,
});