diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 75be36474222f..c430e509b6479 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2065,6 +2065,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var autoType = createIntrinsicType(TypeFlags.Any, "any", ObjectFlags.NonInferrableType, "auto"); var wildcardType = createIntrinsicType(TypeFlags.Any, "any", /*objectFlags*/ undefined, "wildcard"); var blockedStringType = createIntrinsicType(TypeFlags.Any, "any", /*objectFlags*/ undefined, "blocked string"); + var contextFreeType = createIntrinsicType(TypeFlags.Any, "any", /*objectFlags*/ undefined, "context free"); var errorType = createIntrinsicType(TypeFlags.Any, "error"); var unresolvedType = createIntrinsicType(TypeFlags.Any, "unresolved"); var nonInferrableAnyType = createIntrinsicType(TypeFlags.Any, "any", ObjectFlags.ContainsWideningType, "non-inferrable"); @@ -41198,10 +41199,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { types.push(isTypeAssignableTo(type, templateConstraintType) ? type : stringType); } const evaluated = node.parent.kind !== SyntaxKind.TaggedTemplateExpression && evaluate(node).value; - if (evaluated) { + if (typeof evaluated === "string") { return getFreshTypeOfLiteralType(getStringLiteralType(evaluated)); } - if (isConstContext(node) || isTemplateLiteralContext(node) || someType(getContextualType(node, /*contextFlags*/ undefined) || unknownType, isTemplateLiteralContextualType)) { + if (isConstContext(node) || isTemplateLiteralContext(node)) { + return getTemplateLiteralType(texts, types); + } + const contextualType = getContextualType(node, /*contextFlags*/ undefined) || unknownType; + if (contextualType === contextFreeType ? every(types, t => isLiteralType(t) || isPatternLiteralPlaceholderType(t)) : someType(contextualType, isTemplateLiteralContextualType)) { return getTemplateLiteralType(texts, types); } return stringType; @@ -41651,7 +41656,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (links.contextFreeType) { return links.contextFreeType; } - pushContextualType(node, anyType, /*isCache*/ false); + pushContextualType(node, contextFreeType, /*isCache*/ false); const type = links.contextFreeType = checkExpression(node, CheckMode.SkipContextSensitive); popContextualType(); return type; diff --git a/tests/baselines/reference/discriminantUsingEvaluatableTemplateExpression.symbols b/tests/baselines/reference/discriminantUsingEvaluatableTemplateExpression.symbols index 476ad7f878d25..7291a6f563333 100644 --- a/tests/baselines/reference/discriminantUsingEvaluatableTemplateExpression.symbols +++ b/tests/baselines/reference/discriminantUsingEvaluatableTemplateExpression.symbols @@ -37,3 +37,35 @@ foo({ }, }); +type E1 = { d: "main1-sub1"; cb: (x: string) => void }; +>E1 : Symbol(E1, Decl(discriminantUsingEvaluatableTemplateExpression.ts, 12, 3)) +>d : Symbol(d, Decl(discriminantUsingEvaluatableTemplateExpression.ts, 14, 11)) +>cb : Symbol(cb, Decl(discriminantUsingEvaluatableTemplateExpression.ts, 14, 28)) +>x : Symbol(x, Decl(discriminantUsingEvaluatableTemplateExpression.ts, 14, 34)) + +type E2 = { d: "main2-sub2"; cb: (x: number) => void }; +>E2 : Symbol(E2, Decl(discriminantUsingEvaluatableTemplateExpression.ts, 14, 55)) +>d : Symbol(d, Decl(discriminantUsingEvaluatableTemplateExpression.ts, 15, 11)) +>cb : Symbol(cb, Decl(discriminantUsingEvaluatableTemplateExpression.ts, 15, 28)) +>x : Symbol(x, Decl(discriminantUsingEvaluatableTemplateExpression.ts, 15, 34)) + +declare function bar(_: E1 | E2): void; +>bar : Symbol(bar, Decl(discriminantUsingEvaluatableTemplateExpression.ts, 15, 55)) +>_ : Symbol(_, Decl(discriminantUsingEvaluatableTemplateExpression.ts, 17, 21)) +>E1 : Symbol(E1, Decl(discriminantUsingEvaluatableTemplateExpression.ts, 12, 3)) +>E2 : Symbol(E2, Decl(discriminantUsingEvaluatableTemplateExpression.ts, 14, 55)) + +const someCategory = "main1"; +>someCategory : Symbol(someCategory, Decl(discriminantUsingEvaluatableTemplateExpression.ts, 19, 5)) + +const someSubcategory = "sub1"; +>someSubcategory : Symbol(someSubcategory, Decl(discriminantUsingEvaluatableTemplateExpression.ts, 20, 5)) + +bar({ d: `${someCategory}-${someSubcategory}`, cb: (x) => {} }); +>bar : Symbol(bar, Decl(discriminantUsingEvaluatableTemplateExpression.ts, 15, 55)) +>d : Symbol(d, Decl(discriminantUsingEvaluatableTemplateExpression.ts, 22, 5)) +>someCategory : Symbol(someCategory, Decl(discriminantUsingEvaluatableTemplateExpression.ts, 19, 5)) +>someSubcategory : Symbol(someSubcategory, Decl(discriminantUsingEvaluatableTemplateExpression.ts, 20, 5)) +>cb : Symbol(cb, Decl(discriminantUsingEvaluatableTemplateExpression.ts, 22, 46)) +>x : Symbol(x, Decl(discriminantUsingEvaluatableTemplateExpression.ts, 22, 52)) + diff --git a/tests/baselines/reference/discriminantUsingEvaluatableTemplateExpression.types b/tests/baselines/reference/discriminantUsingEvaluatableTemplateExpression.types index ba438f143f0b7..a3b8073e3dee2 100644 --- a/tests/baselines/reference/discriminantUsingEvaluatableTemplateExpression.types +++ b/tests/baselines/reference/discriminantUsingEvaluatableTemplateExpression.types @@ -60,3 +60,63 @@ foo({ }, }); +type E1 = { d: "main1-sub1"; cb: (x: string) => void }; +>E1 : E1 +> : ^^ +>d : "main1-sub1" +> : ^^^^^^^^^^^^ +>cb : (x: string) => void +> : ^ ^^ ^^^^^ +>x : string +> : ^^^^^^ + +type E2 = { d: "main2-sub2"; cb: (x: number) => void }; +>E2 : E2 +> : ^^ +>d : "main2-sub2" +> : ^^^^^^^^^^^^ +>cb : (x: number) => void +> : ^ ^^ ^^^^^ +>x : number +> : ^^^^^^ + +declare function bar(_: E1 | E2): void; +>bar : (_: E1 | E2) => void +> : ^ ^^ ^^^^^ +>_ : E1 | E2 +> : ^^^^^^^ + +const someCategory = "main1"; +>someCategory : "main1" +> : ^^^^^^^ +>"main1" : "main1" +> : ^^^^^^^ + +const someSubcategory = "sub1"; +>someSubcategory : "sub1" +> : ^^^^^^ +>"sub1" : "sub1" +> : ^^^^^^ + +bar({ d: `${someCategory}-${someSubcategory}`, cb: (x) => {} }); +>bar({ d: `${someCategory}-${someSubcategory}`, cb: (x) => {} }) : void +> : ^^^^ +>bar : (_: E1 | E2) => void +> : ^ ^^ ^^^^^ +>{ d: `${someCategory}-${someSubcategory}`, cb: (x) => {} } : { d: "main1-sub1"; cb: (x: string) => void; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^ +>d : "main1-sub1" +> : ^^^^^^^^^^^^ +>`${someCategory}-${someSubcategory}` : "main1-sub1" +> : ^^^^^^^^^^^^ +>someCategory : "main1" +> : ^^^^^^^ +>someSubcategory : "sub1" +> : ^^^^^^ +>cb : (x: string) => void +> : ^ ^^^^^^^^^^^^^^^^^ +>(x) => {} : (x: string) => void +> : ^ ^^^^^^^^^^^^^^^^^ +>x : string +> : ^^^^^^ + diff --git a/tests/baselines/reference/discriminatedUnionTypesOverlappingDiscriminants1.errors.txt b/tests/baselines/reference/discriminatedUnionTypesOverlappingDiscriminants1.errors.txt new file mode 100644 index 0000000000000..b9b087ccc0b47 --- /dev/null +++ b/tests/baselines/reference/discriminatedUnionTypesOverlappingDiscriminants1.errors.txt @@ -0,0 +1,196 @@ +discriminatedUnionTypesOverlappingDiscriminants1.ts(83,7): error TS2322: Type '{ audience: "earth"; meal: "vegetable_cow"; }' is not assignable to type 'Target'. + Types of property 'meal' are incompatible. + Type '"vegetable_cow"' is not assignable to type 'Custom | "fruit_apple" | "fruit_orange" | "vegetable_spinach" | "vegetable_carrot" | "other_milk" | "other_water"'. Did you mean '"vegetable_carrot"'? +discriminatedUnionTypesOverlappingDiscriminants1.ts(89,7): error TS2322: Type '{ meal: string; audience: "earth"; }' is not assignable to type 'Target'. + Types of property 'audience' are incompatible. + Type '"earth"' is not assignable to type '"mars" | "jupiter"'. +discriminatedUnionTypesOverlappingDiscriminants1.ts(97,7): error TS2322: Type '{ audience: "earth"; meal: "vegetable_cow"; }' is not assignable to type 'Target'. + Types of property 'meal' are incompatible. + Type '"vegetable_cow"' is not assignable to type 'Custom | "fruit_apple" | "fruit_orange" | "vegetable_spinach" | "vegetable_carrot" | "other_milk" | "other_water"'. Did you mean '"vegetable_carrot"'? +discriminatedUnionTypesOverlappingDiscriminants1.ts(103,7): error TS2322: Type '{ meal: string; audience: "earth"; }' is not assignable to type 'Target'. + Types of property 'audience' are incompatible. + Type '"earth"' is not assignable to type '"mars" | "jupiter"'. +discriminatedUnionTypesOverlappingDiscriminants1.ts(111,7): error TS2322: Type '{ audience: "earth"; meal: "vegetable_cow"; }' is not assignable to type 'Target'. + Types of property 'meal' are incompatible. + Type '"vegetable_cow"' is not assignable to type 'Custom | "fruit_apple" | "fruit_orange" | "vegetable_spinach" | "vegetable_carrot" | "other_milk" | "other_water"'. Did you mean '"vegetable_carrot"'? +discriminatedUnionTypesOverlappingDiscriminants1.ts(117,7): error TS2322: Type '{ meal: string; audience: "earth"; }' is not assignable to type 'Target'. + Types of property 'audience' are incompatible. + Type '"earth"' is not assignable to type '"mars" | "jupiter"'. +discriminatedUnionTypesOverlappingDiscriminants1.ts(125,7): error TS2322: Type '{ audience: "earth"; meal: "vegetable_cow" | "vegetable_pig"; }' is not assignable to type 'Target'. + Types of property 'meal' are incompatible. + Type '"vegetable_cow" | "vegetable_pig"' is not assignable to type 'Custom | "fruit_apple" | "fruit_orange" | "vegetable_spinach" | "vegetable_carrot" | "other_milk" | "other_water"'. + Type '"vegetable_cow"' is not assignable to type 'Custom | "fruit_apple" | "fruit_orange" | "vegetable_spinach" | "vegetable_carrot" | "other_milk" | "other_water"'. Did you mean '"vegetable_carrot"'? +discriminatedUnionTypesOverlappingDiscriminants1.ts(131,7): error TS2322: Type '{ meal: string; audience: "earth"; }' is not assignable to type 'Target'. + Types of property 'audience' are incompatible. + Type '"earth"' is not assignable to type '"mars" | "jupiter"'. + + +==== discriminatedUnionTypesOverlappingDiscriminants1.ts (8 errors) ==== + // https://github.com/microsoft/TypeScript/issues/57231 + + type Food = "apple" | "orange"; + type Vegetable = "spinach" | "carrot"; + type Other = "milk" | "water"; + type Custom = "air" | "soil"; + + type Target = + | { + audience: "earth"; + meal: + | Custom + | `fruit_${Food}` + | `vegetable_${Vegetable}` + | `other_${Other}`; + } + | { + audience: "mars" | "jupiter"; + meal: string; + }; + + const target1: Target = { + audience: "earth", + meal: `vegetable_carrot`, + }; + + const target2: Target = { + meal: `vegetable_carrot`, + audience: "earth", + }; + + const typedVegetableWithInitializer: Vegetable = 'carrot'; + + const target3: Target = { + audience: "earth", + meal: `vegetable_${typedVegetableWithInitializer}`, + }; + + const target4: Target = { + meal: `vegetable_${typedVegetableWithInitializer}`, + audience: "earth", + }; + + const typedCarrotWithInitializer: "carrot" = 'carrot'; + + const target5: Target = { + audience: "earth", + meal: `vegetable_${typedCarrotWithInitializer}`, + }; + + const target6: Target = { + meal: `vegetable_${typedCarrotWithInitializer}`, + audience: "earth", + }; + + const carrotInitializer = 'carrot'; + + const target7: Target = { + audience: "earth", + meal: `vegetable_${carrotInitializer}`, + }; + + const target8: Target = { + meal: `vegetable_${carrotInitializer}`, + audience: "earth", + }; + + declare const vegetable: Vegetable; + + const target9: Target = { + audience: "earth", + meal: `vegetable_${vegetable}`, + }; + + const target10: Target = { + meal: `vegetable_${vegetable}`, + audience: "earth", + }; + + const typedNonVegetableWithInitializer: "cow" | "pig" = "cow"; + + // error + const target11: Target = { + ~~~~~~~~ +!!! error TS2322: Type '{ audience: "earth"; meal: "vegetable_cow"; }' is not assignable to type 'Target'. +!!! error TS2322: Types of property 'meal' are incompatible. +!!! error TS2322: Type '"vegetable_cow"' is not assignable to type 'Custom | "fruit_apple" | "fruit_orange" | "vegetable_spinach" | "vegetable_carrot" | "other_milk" | "other_water"'. Did you mean '"vegetable_carrot"'? + audience: "earth", + meal: `vegetable_${typedNonVegetableWithInitializer}`, + }; + + // error + const target12: Target = { + ~~~~~~~~ +!!! error TS2322: Type '{ meal: string; audience: "earth"; }' is not assignable to type 'Target'. +!!! error TS2322: Types of property 'audience' are incompatible. +!!! error TS2322: Type '"earth"' is not assignable to type '"mars" | "jupiter"'. + meal: `vegetable_${typedNonVegetableWithInitializer}`, + audience: "earth", + }; + + const typedCowWithInitializer: "cow" = "cow"; + + // error + const target13: Target = { + ~~~~~~~~ +!!! error TS2322: Type '{ audience: "earth"; meal: "vegetable_cow"; }' is not assignable to type 'Target'. +!!! error TS2322: Types of property 'meal' are incompatible. +!!! error TS2322: Type '"vegetable_cow"' is not assignable to type 'Custom | "fruit_apple" | "fruit_orange" | "vegetable_spinach" | "vegetable_carrot" | "other_milk" | "other_water"'. Did you mean '"vegetable_carrot"'? + audience: "earth", + meal: `vegetable_${typedCowWithInitializer}`, + }; + + // error + const target14: Target = { + ~~~~~~~~ +!!! error TS2322: Type '{ meal: string; audience: "earth"; }' is not assignable to type 'Target'. +!!! error TS2322: Types of property 'audience' are incompatible. +!!! error TS2322: Type '"earth"' is not assignable to type '"mars" | "jupiter"'. + meal: `vegetable_${typedCowWithInitializer}`, + audience: "earth", + }; + + const cowInitializer = "cow"; + + // error + const target15: Target = { + ~~~~~~~~ +!!! error TS2322: Type '{ audience: "earth"; meal: "vegetable_cow"; }' is not assignable to type 'Target'. +!!! error TS2322: Types of property 'meal' are incompatible. +!!! error TS2322: Type '"vegetable_cow"' is not assignable to type 'Custom | "fruit_apple" | "fruit_orange" | "vegetable_spinach" | "vegetable_carrot" | "other_milk" | "other_water"'. Did you mean '"vegetable_carrot"'? + audience: "earth", + meal: `vegetable_${cowInitializer}`, + }; + + // error + const target16: Target = { + ~~~~~~~~ +!!! error TS2322: Type '{ meal: string; audience: "earth"; }' is not assignable to type 'Target'. +!!! error TS2322: Types of property 'audience' are incompatible. +!!! error TS2322: Type '"earth"' is not assignable to type '"mars" | "jupiter"'. + meal: `vegetable_${cowInitializer}`, + audience: "earth", + }; + + declare const nonVegetable: "cow" | "pig"; + + // error + const target17: Target = { + ~~~~~~~~ +!!! error TS2322: Type '{ audience: "earth"; meal: "vegetable_cow" | "vegetable_pig"; }' is not assignable to type 'Target'. +!!! error TS2322: Types of property 'meal' are incompatible. +!!! error TS2322: Type '"vegetable_cow" | "vegetable_pig"' is not assignable to type 'Custom | "fruit_apple" | "fruit_orange" | "vegetable_spinach" | "vegetable_carrot" | "other_milk" | "other_water"'. +!!! error TS2322: Type '"vegetable_cow"' is not assignable to type 'Custom | "fruit_apple" | "fruit_orange" | "vegetable_spinach" | "vegetable_carrot" | "other_milk" | "other_water"'. Did you mean '"vegetable_carrot"'? + audience: "earth", + meal: `vegetable_${nonVegetable}`, + }; + + // error + const target18: Target = { + ~~~~~~~~ +!!! error TS2322: Type '{ meal: string; audience: "earth"; }' is not assignable to type 'Target'. +!!! error TS2322: Types of property 'audience' are incompatible. +!!! error TS2322: Type '"earth"' is not assignable to type '"mars" | "jupiter"'. + meal: `vegetable_${nonVegetable}`, + audience: "earth", + }; + \ No newline at end of file diff --git a/tests/baselines/reference/discriminatedUnionTypesOverlappingDiscriminants1.symbols b/tests/baselines/reference/discriminatedUnionTypesOverlappingDiscriminants1.symbols new file mode 100644 index 0000000000000..6c07383e57a18 --- /dev/null +++ b/tests/baselines/reference/discriminatedUnionTypesOverlappingDiscriminants1.symbols @@ -0,0 +1,314 @@ +//// [tests/cases/conformance/types/union/discriminatedUnionTypesOverlappingDiscriminants1.ts] //// + +=== discriminatedUnionTypesOverlappingDiscriminants1.ts === +// https://github.com/microsoft/TypeScript/issues/57231 + +type Food = "apple" | "orange"; +>Food : Symbol(Food, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 0, 0)) + +type Vegetable = "spinach" | "carrot"; +>Vegetable : Symbol(Vegetable, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 2, 31)) + +type Other = "milk" | "water"; +>Other : Symbol(Other, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 3, 38)) + +type Custom = "air" | "soil"; +>Custom : Symbol(Custom, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 4, 30)) + +type Target = +>Target : Symbol(Target, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 5, 29)) + + | { + audience: "earth"; +>audience : Symbol(audience, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 8, 5)) + + meal: +>meal : Symbol(meal, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 9, 24)) + + | Custom +>Custom : Symbol(Custom, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 4, 30)) + + | `fruit_${Food}` +>Food : Symbol(Food, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 0, 0)) + + | `vegetable_${Vegetable}` +>Vegetable : Symbol(Vegetable, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 2, 31)) + + | `other_${Other}`; +>Other : Symbol(Other, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 3, 38)) + } + | { + audience: "mars" | "jupiter"; +>audience : Symbol(audience, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 16, 5)) + + meal: string; +>meal : Symbol(meal, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 17, 35)) + + }; + +const target1: Target = { +>target1 : Symbol(target1, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 21, 5)) +>Target : Symbol(Target, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 5, 29)) + + audience: "earth", +>audience : Symbol(audience, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 21, 25)) + + meal: `vegetable_carrot`, +>meal : Symbol(meal, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 22, 20)) + +}; + +const target2: Target = { +>target2 : Symbol(target2, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 26, 5)) +>Target : Symbol(Target, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 5, 29)) + + meal: `vegetable_carrot`, +>meal : Symbol(meal, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 26, 25)) + + audience: "earth", +>audience : Symbol(audience, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 27, 27)) + +}; + +const typedVegetableWithInitializer: Vegetable = 'carrot'; +>typedVegetableWithInitializer : Symbol(typedVegetableWithInitializer, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 31, 5)) +>Vegetable : Symbol(Vegetable, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 2, 31)) + +const target3: Target = { +>target3 : Symbol(target3, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 33, 5)) +>Target : Symbol(Target, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 5, 29)) + + audience: "earth", +>audience : Symbol(audience, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 33, 25)) + + meal: `vegetable_${typedVegetableWithInitializer}`, +>meal : Symbol(meal, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 34, 20)) +>typedVegetableWithInitializer : Symbol(typedVegetableWithInitializer, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 31, 5)) + +}; + +const target4: Target = { +>target4 : Symbol(target4, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 38, 5)) +>Target : Symbol(Target, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 5, 29)) + + meal: `vegetable_${typedVegetableWithInitializer}`, +>meal : Symbol(meal, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 38, 25)) +>typedVegetableWithInitializer : Symbol(typedVegetableWithInitializer, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 31, 5)) + + audience: "earth", +>audience : Symbol(audience, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 39, 53)) + +}; + +const typedCarrotWithInitializer: "carrot" = 'carrot'; +>typedCarrotWithInitializer : Symbol(typedCarrotWithInitializer, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 43, 5)) + +const target5: Target = { +>target5 : Symbol(target5, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 45, 5)) +>Target : Symbol(Target, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 5, 29)) + + audience: "earth", +>audience : Symbol(audience, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 45, 25)) + + meal: `vegetable_${typedCarrotWithInitializer}`, +>meal : Symbol(meal, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 46, 20)) +>typedCarrotWithInitializer : Symbol(typedCarrotWithInitializer, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 43, 5)) + +}; + +const target6: Target = { +>target6 : Symbol(target6, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 50, 5)) +>Target : Symbol(Target, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 5, 29)) + + meal: `vegetable_${typedCarrotWithInitializer}`, +>meal : Symbol(meal, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 50, 25)) +>typedCarrotWithInitializer : Symbol(typedCarrotWithInitializer, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 43, 5)) + + audience: "earth", +>audience : Symbol(audience, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 51, 50)) + +}; + +const carrotInitializer = 'carrot'; +>carrotInitializer : Symbol(carrotInitializer, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 55, 5)) + +const target7: Target = { +>target7 : Symbol(target7, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 57, 5)) +>Target : Symbol(Target, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 5, 29)) + + audience: "earth", +>audience : Symbol(audience, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 57, 25)) + + meal: `vegetable_${carrotInitializer}`, +>meal : Symbol(meal, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 58, 20)) +>carrotInitializer : Symbol(carrotInitializer, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 55, 5)) + +}; + +const target8: Target = { +>target8 : Symbol(target8, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 62, 5)) +>Target : Symbol(Target, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 5, 29)) + + meal: `vegetable_${carrotInitializer}`, +>meal : Symbol(meal, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 62, 25)) +>carrotInitializer : Symbol(carrotInitializer, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 55, 5)) + + audience: "earth", +>audience : Symbol(audience, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 63, 41)) + +}; + +declare const vegetable: Vegetable; +>vegetable : Symbol(vegetable, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 67, 13)) +>Vegetable : Symbol(Vegetable, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 2, 31)) + +const target9: Target = { +>target9 : Symbol(target9, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 69, 5)) +>Target : Symbol(Target, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 5, 29)) + + audience: "earth", +>audience : Symbol(audience, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 69, 25)) + + meal: `vegetable_${vegetable}`, +>meal : Symbol(meal, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 70, 20)) +>vegetable : Symbol(vegetable, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 67, 13)) + +}; + +const target10: Target = { +>target10 : Symbol(target10, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 74, 5)) +>Target : Symbol(Target, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 5, 29)) + + meal: `vegetable_${vegetable}`, +>meal : Symbol(meal, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 74, 26)) +>vegetable : Symbol(vegetable, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 67, 13)) + + audience: "earth", +>audience : Symbol(audience, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 75, 33)) + +}; + +const typedNonVegetableWithInitializer: "cow" | "pig" = "cow"; +>typedNonVegetableWithInitializer : Symbol(typedNonVegetableWithInitializer, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 79, 5)) + +// error +const target11: Target = { +>target11 : Symbol(target11, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 82, 5)) +>Target : Symbol(Target, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 5, 29)) + + audience: "earth", +>audience : Symbol(audience, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 82, 26)) + + meal: `vegetable_${typedNonVegetableWithInitializer}`, +>meal : Symbol(meal, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 83, 20)) +>typedNonVegetableWithInitializer : Symbol(typedNonVegetableWithInitializer, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 79, 5)) + +}; + +// error +const target12: Target = { +>target12 : Symbol(target12, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 88, 5)) +>Target : Symbol(Target, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 5, 29)) + + meal: `vegetable_${typedNonVegetableWithInitializer}`, +>meal : Symbol(meal, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 88, 26)) +>typedNonVegetableWithInitializer : Symbol(typedNonVegetableWithInitializer, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 79, 5)) + + audience: "earth", +>audience : Symbol(audience, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 89, 56)) + +}; + +const typedCowWithInitializer: "cow" = "cow"; +>typedCowWithInitializer : Symbol(typedCowWithInitializer, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 93, 5)) + +// error +const target13: Target = { +>target13 : Symbol(target13, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 96, 5)) +>Target : Symbol(Target, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 5, 29)) + + audience: "earth", +>audience : Symbol(audience, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 96, 26)) + + meal: `vegetable_${typedCowWithInitializer}`, +>meal : Symbol(meal, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 97, 20)) +>typedCowWithInitializer : Symbol(typedCowWithInitializer, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 93, 5)) + +}; + +// error +const target14: Target = { +>target14 : Symbol(target14, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 102, 5)) +>Target : Symbol(Target, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 5, 29)) + + meal: `vegetable_${typedCowWithInitializer}`, +>meal : Symbol(meal, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 102, 26)) +>typedCowWithInitializer : Symbol(typedCowWithInitializer, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 93, 5)) + + audience: "earth", +>audience : Symbol(audience, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 103, 47)) + +}; + +const cowInitializer = "cow"; +>cowInitializer : Symbol(cowInitializer, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 107, 5)) + +// error +const target15: Target = { +>target15 : Symbol(target15, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 110, 5)) +>Target : Symbol(Target, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 5, 29)) + + audience: "earth", +>audience : Symbol(audience, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 110, 26)) + + meal: `vegetable_${cowInitializer}`, +>meal : Symbol(meal, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 111, 20)) +>cowInitializer : Symbol(cowInitializer, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 107, 5)) + +}; + +// error +const target16: Target = { +>target16 : Symbol(target16, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 116, 5)) +>Target : Symbol(Target, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 5, 29)) + + meal: `vegetable_${cowInitializer}`, +>meal : Symbol(meal, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 116, 26)) +>cowInitializer : Symbol(cowInitializer, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 107, 5)) + + audience: "earth", +>audience : Symbol(audience, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 117, 38)) + +}; + +declare const nonVegetable: "cow" | "pig"; +>nonVegetable : Symbol(nonVegetable, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 121, 13)) + +// error +const target17: Target = { +>target17 : Symbol(target17, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 124, 5)) +>Target : Symbol(Target, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 5, 29)) + + audience: "earth", +>audience : Symbol(audience, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 124, 26)) + + meal: `vegetable_${nonVegetable}`, +>meal : Symbol(meal, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 125, 20)) +>nonVegetable : Symbol(nonVegetable, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 121, 13)) + +}; + +// error +const target18: Target = { +>target18 : Symbol(target18, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 130, 5)) +>Target : Symbol(Target, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 5, 29)) + + meal: `vegetable_${nonVegetable}`, +>meal : Symbol(meal, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 130, 26)) +>nonVegetable : Symbol(nonVegetable, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 121, 13)) + + audience: "earth", +>audience : Symbol(audience, Decl(discriminatedUnionTypesOverlappingDiscriminants1.ts, 131, 36)) + +}; + diff --git a/tests/baselines/reference/discriminatedUnionTypesOverlappingDiscriminants1.types b/tests/baselines/reference/discriminatedUnionTypesOverlappingDiscriminants1.types new file mode 100644 index 0000000000000..0449337c19f6f --- /dev/null +++ b/tests/baselines/reference/discriminatedUnionTypesOverlappingDiscriminants1.types @@ -0,0 +1,494 @@ +//// [tests/cases/conformance/types/union/discriminatedUnionTypesOverlappingDiscriminants1.ts] //// + +=== discriminatedUnionTypesOverlappingDiscriminants1.ts === +// https://github.com/microsoft/TypeScript/issues/57231 + +type Food = "apple" | "orange"; +>Food : Food +> : ^^^^ + +type Vegetable = "spinach" | "carrot"; +>Vegetable : Vegetable +> : ^^^^^^^^^ + +type Other = "milk" | "water"; +>Other : Other +> : ^^^^^ + +type Custom = "air" | "soil"; +>Custom : Custom +> : ^^^^^^ + +type Target = +>Target : Target +> : ^^^^^^ + + | { + audience: "earth"; +>audience : "earth" +> : ^^^^^^^ + + meal: +>meal : Custom | "fruit_apple" | "fruit_orange" | "vegetable_spinach" | "vegetable_carrot" | "other_milk" | "other_water" +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + | Custom + | `fruit_${Food}` + | `vegetable_${Vegetable}` + | `other_${Other}`; + } + | { + audience: "mars" | "jupiter"; +>audience : "mars" | "jupiter" +> : ^^^^^^^^^^^^^^^^^^ + + meal: string; +>meal : string +> : ^^^^^^ + + }; + +const target1: Target = { +>target1 : Target +> : ^^^^^^ +>{ audience: "earth", meal: `vegetable_carrot`,} : { audience: "earth"; meal: "vegetable_carrot"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + audience: "earth", +>audience : "earth" +> : ^^^^^^^ +>"earth" : "earth" +> : ^^^^^^^ + + meal: `vegetable_carrot`, +>meal : "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^ +>`vegetable_carrot` : "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^ + +}; + +const target2: Target = { +>target2 : Target +> : ^^^^^^ +>{ meal: `vegetable_carrot`, audience: "earth",} : { meal: "vegetable_carrot"; audience: "earth"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + meal: `vegetable_carrot`, +>meal : "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^ +>`vegetable_carrot` : "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^ + + audience: "earth", +>audience : "earth" +> : ^^^^^^^ +>"earth" : "earth" +> : ^^^^^^^ + +}; + +const typedVegetableWithInitializer: Vegetable = 'carrot'; +>typedVegetableWithInitializer : Vegetable +> : ^^^^^^^^^ +>'carrot' : "carrot" +> : ^^^^^^^^ + +const target3: Target = { +>target3 : Target +> : ^^^^^^ +>{ audience: "earth", meal: `vegetable_${typedVegetableWithInitializer}`,} : { audience: "earth"; meal: "vegetable_carrot"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + audience: "earth", +>audience : "earth" +> : ^^^^^^^ +>"earth" : "earth" +> : ^^^^^^^ + + meal: `vegetable_${typedVegetableWithInitializer}`, +>meal : "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^ +>`vegetable_${typedVegetableWithInitializer}` : "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^ +>typedVegetableWithInitializer : "carrot" +> : ^^^^^^^^ + +}; + +const target4: Target = { +>target4 : Target +> : ^^^^^^ +>{ meal: `vegetable_${typedVegetableWithInitializer}`, audience: "earth",} : { meal: "vegetable_carrot"; audience: "earth"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + meal: `vegetable_${typedVegetableWithInitializer}`, +>meal : "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^ +>`vegetable_${typedVegetableWithInitializer}` : "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^ +>typedVegetableWithInitializer : "carrot" +> : ^^^^^^^^ + + audience: "earth", +>audience : "earth" +> : ^^^^^^^ +>"earth" : "earth" +> : ^^^^^^^ + +}; + +const typedCarrotWithInitializer: "carrot" = 'carrot'; +>typedCarrotWithInitializer : "carrot" +> : ^^^^^^^^ +>'carrot' : "carrot" +> : ^^^^^^^^ + +const target5: Target = { +>target5 : Target +> : ^^^^^^ +>{ audience: "earth", meal: `vegetable_${typedCarrotWithInitializer}`,} : { audience: "earth"; meal: "vegetable_carrot"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + audience: "earth", +>audience : "earth" +> : ^^^^^^^ +>"earth" : "earth" +> : ^^^^^^^ + + meal: `vegetable_${typedCarrotWithInitializer}`, +>meal : "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^ +>`vegetable_${typedCarrotWithInitializer}` : "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^ +>typedCarrotWithInitializer : "carrot" +> : ^^^^^^^^ + +}; + +const target6: Target = { +>target6 : Target +> : ^^^^^^ +>{ meal: `vegetable_${typedCarrotWithInitializer}`, audience: "earth",} : { meal: "vegetable_carrot"; audience: "earth"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + meal: `vegetable_${typedCarrotWithInitializer}`, +>meal : "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^ +>`vegetable_${typedCarrotWithInitializer}` : "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^ +>typedCarrotWithInitializer : "carrot" +> : ^^^^^^^^ + + audience: "earth", +>audience : "earth" +> : ^^^^^^^ +>"earth" : "earth" +> : ^^^^^^^ + +}; + +const carrotInitializer = 'carrot'; +>carrotInitializer : "carrot" +> : ^^^^^^^^ +>'carrot' : "carrot" +> : ^^^^^^^^ + +const target7: Target = { +>target7 : Target +> : ^^^^^^ +>{ audience: "earth", meal: `vegetable_${carrotInitializer}`,} : { audience: "earth"; meal: "vegetable_carrot"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + audience: "earth", +>audience : "earth" +> : ^^^^^^^ +>"earth" : "earth" +> : ^^^^^^^ + + meal: `vegetable_${carrotInitializer}`, +>meal : "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^ +>`vegetable_${carrotInitializer}` : "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^ +>carrotInitializer : "carrot" +> : ^^^^^^^^ + +}; + +const target8: Target = { +>target8 : Target +> : ^^^^^^ +>{ meal: `vegetable_${carrotInitializer}`, audience: "earth",} : { meal: "vegetable_carrot"; audience: "earth"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + meal: `vegetable_${carrotInitializer}`, +>meal : "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^ +>`vegetable_${carrotInitializer}` : "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^ +>carrotInitializer : "carrot" +> : ^^^^^^^^ + + audience: "earth", +>audience : "earth" +> : ^^^^^^^ +>"earth" : "earth" +> : ^^^^^^^ + +}; + +declare const vegetable: Vegetable; +>vegetable : Vegetable +> : ^^^^^^^^^ + +const target9: Target = { +>target9 : Target +> : ^^^^^^ +>{ audience: "earth", meal: `vegetable_${vegetable}`,} : { audience: "earth"; meal: "vegetable_spinach" | "vegetable_carrot"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + audience: "earth", +>audience : "earth" +> : ^^^^^^^ +>"earth" : "earth" +> : ^^^^^^^ + + meal: `vegetable_${vegetable}`, +>meal : "vegetable_spinach" | "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>`vegetable_${vegetable}` : "vegetable_spinach" | "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>vegetable : Vegetable +> : ^^^^^^^^^ + +}; + +const target10: Target = { +>target10 : Target +> : ^^^^^^ +>{ meal: `vegetable_${vegetable}`, audience: "earth",} : { meal: "vegetable_spinach" | "vegetable_carrot"; audience: "earth"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + meal: `vegetable_${vegetable}`, +>meal : "vegetable_spinach" | "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>`vegetable_${vegetable}` : "vegetable_spinach" | "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>vegetable : Vegetable +> : ^^^^^^^^^ + + audience: "earth", +>audience : "earth" +> : ^^^^^^^ +>"earth" : "earth" +> : ^^^^^^^ + +}; + +const typedNonVegetableWithInitializer: "cow" | "pig" = "cow"; +>typedNonVegetableWithInitializer : "cow" | "pig" +> : ^^^^^^^^^^^^^ +>"cow" : "cow" +> : ^^^^^ + +// error +const target11: Target = { +>target11 : Target +> : ^^^^^^ +>{ audience: "earth", meal: `vegetable_${typedNonVegetableWithInitializer}`,} : { audience: "earth"; meal: "vegetable_cow"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + audience: "earth", +>audience : "earth" +> : ^^^^^^^ +>"earth" : "earth" +> : ^^^^^^^ + + meal: `vegetable_${typedNonVegetableWithInitializer}`, +>meal : "vegetable_cow" +> : ^^^^^^^^^^^^^^^ +>`vegetable_${typedNonVegetableWithInitializer}` : "vegetable_cow" +> : ^^^^^^^^^^^^^^^ +>typedNonVegetableWithInitializer : "cow" +> : ^^^^^ + +}; + +// error +const target12: Target = { +>target12 : Target +> : ^^^^^^ +>{ meal: `vegetable_${typedNonVegetableWithInitializer}`, audience: "earth",} : { meal: string; audience: "earth"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + meal: `vegetable_${typedNonVegetableWithInitializer}`, +>meal : string +> : ^^^^^^ +>`vegetable_${typedNonVegetableWithInitializer}` : string +> : ^^^^^^ +>typedNonVegetableWithInitializer : "cow" +> : ^^^^^ + + audience: "earth", +>audience : "earth" +> : ^^^^^^^ +>"earth" : "earth" +> : ^^^^^^^ + +}; + +const typedCowWithInitializer: "cow" = "cow"; +>typedCowWithInitializer : "cow" +> : ^^^^^ +>"cow" : "cow" +> : ^^^^^ + +// error +const target13: Target = { +>target13 : Target +> : ^^^^^^ +>{ audience: "earth", meal: `vegetable_${typedCowWithInitializer}`,} : { audience: "earth"; meal: "vegetable_cow"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + audience: "earth", +>audience : "earth" +> : ^^^^^^^ +>"earth" : "earth" +> : ^^^^^^^ + + meal: `vegetable_${typedCowWithInitializer}`, +>meal : "vegetable_cow" +> : ^^^^^^^^^^^^^^^ +>`vegetable_${typedCowWithInitializer}` : "vegetable_cow" +> : ^^^^^^^^^^^^^^^ +>typedCowWithInitializer : "cow" +> : ^^^^^ + +}; + +// error +const target14: Target = { +>target14 : Target +> : ^^^^^^ +>{ meal: `vegetable_${typedCowWithInitializer}`, audience: "earth",} : { meal: string; audience: "earth"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + meal: `vegetable_${typedCowWithInitializer}`, +>meal : string +> : ^^^^^^ +>`vegetable_${typedCowWithInitializer}` : string +> : ^^^^^^ +>typedCowWithInitializer : "cow" +> : ^^^^^ + + audience: "earth", +>audience : "earth" +> : ^^^^^^^ +>"earth" : "earth" +> : ^^^^^^^ + +}; + +const cowInitializer = "cow"; +>cowInitializer : "cow" +> : ^^^^^ +>"cow" : "cow" +> : ^^^^^ + +// error +const target15: Target = { +>target15 : Target +> : ^^^^^^ +>{ audience: "earth", meal: `vegetable_${cowInitializer}`,} : { audience: "earth"; meal: "vegetable_cow"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + audience: "earth", +>audience : "earth" +> : ^^^^^^^ +>"earth" : "earth" +> : ^^^^^^^ + + meal: `vegetable_${cowInitializer}`, +>meal : "vegetable_cow" +> : ^^^^^^^^^^^^^^^ +>`vegetable_${cowInitializer}` : "vegetable_cow" +> : ^^^^^^^^^^^^^^^ +>cowInitializer : "cow" +> : ^^^^^ + +}; + +// error +const target16: Target = { +>target16 : Target +> : ^^^^^^ +>{ meal: `vegetable_${cowInitializer}`, audience: "earth",} : { meal: string; audience: "earth"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + meal: `vegetable_${cowInitializer}`, +>meal : string +> : ^^^^^^ +>`vegetable_${cowInitializer}` : "vegetable_cow" +> : ^^^^^^^^^^^^^^^ +>cowInitializer : "cow" +> : ^^^^^ + + audience: "earth", +>audience : "earth" +> : ^^^^^^^ +>"earth" : "earth" +> : ^^^^^^^ + +}; + +declare const nonVegetable: "cow" | "pig"; +>nonVegetable : "cow" | "pig" +> : ^^^^^^^^^^^^^ + +// error +const target17: Target = { +>target17 : Target +> : ^^^^^^ +>{ audience: "earth", meal: `vegetable_${nonVegetable}`,} : { audience: "earth"; meal: "vegetable_cow" | "vegetable_pig"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + audience: "earth", +>audience : "earth" +> : ^^^^^^^ +>"earth" : "earth" +> : ^^^^^^^ + + meal: `vegetable_${nonVegetable}`, +>meal : "vegetable_cow" | "vegetable_pig" +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>`vegetable_${nonVegetable}` : "vegetable_cow" | "vegetable_pig" +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>nonVegetable : "cow" | "pig" +> : ^^^^^^^^^^^^^ + +}; + +// error +const target18: Target = { +>target18 : Target +> : ^^^^^^ +>{ meal: `vegetable_${nonVegetable}`, audience: "earth",} : { meal: string; audience: "earth"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + meal: `vegetable_${nonVegetable}`, +>meal : string +> : ^^^^^^ +>`vegetable_${nonVegetable}` : string +> : ^^^^^^ +>nonVegetable : "cow" | "pig" +> : ^^^^^^^^^^^^^ + + audience: "earth", +>audience : "earth" +> : ^^^^^^^ +>"earth" : "earth" +> : ^^^^^^^ + +}; + diff --git a/tests/baselines/reference/evolvingArrayTemplateLiterals1.symbols b/tests/baselines/reference/evolvingArrayTemplateLiterals1.symbols new file mode 100644 index 0000000000000..375f4e2804126 --- /dev/null +++ b/tests/baselines/reference/evolvingArrayTemplateLiterals1.symbols @@ -0,0 +1,68 @@ +//// [tests/cases/compiler/evolvingArrayTemplateLiterals1.ts] //// + +=== evolvingArrayTemplateLiterals1.ts === +type Vegetable = "spinach" | "carrot"; +>Vegetable : Symbol(Vegetable, Decl(evolvingArrayTemplateLiterals1.ts, 0, 0)) + +const arr1 = []; +>arr1 : Symbol(arr1, Decl(evolvingArrayTemplateLiterals1.ts, 2, 5)) + +const v1 = "carrot"; +>v1 : Symbol(v1, Decl(evolvingArrayTemplateLiterals1.ts, 3, 5)) + +arr1.push(`vegetable_${v1}`); +>arr1.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>arr1 : Symbol(arr1, Decl(evolvingArrayTemplateLiterals1.ts, 2, 5)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>v1 : Symbol(v1, Decl(evolvingArrayTemplateLiterals1.ts, 3, 5)) + +arr1; +>arr1 : Symbol(arr1, Decl(evolvingArrayTemplateLiterals1.ts, 2, 5)) + +const arr2 = []; +>arr2 : Symbol(arr2, Decl(evolvingArrayTemplateLiterals1.ts, 7, 5)) + +const v2: "carrot" = "carrot"; +>v2 : Symbol(v2, Decl(evolvingArrayTemplateLiterals1.ts, 8, 5)) + +arr2.push(`vegetable_${v2}`); +>arr2.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>arr2 : Symbol(arr2, Decl(evolvingArrayTemplateLiterals1.ts, 7, 5)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>v2 : Symbol(v2, Decl(evolvingArrayTemplateLiterals1.ts, 8, 5)) + +arr2; +>arr2 : Symbol(arr2, Decl(evolvingArrayTemplateLiterals1.ts, 7, 5)) + +const arr3 = []; +>arr3 : Symbol(arr3, Decl(evolvingArrayTemplateLiterals1.ts, 12, 5)) + +const v3: Vegetable = "carrot"; +>v3 : Symbol(v3, Decl(evolvingArrayTemplateLiterals1.ts, 13, 5)) +>Vegetable : Symbol(Vegetable, Decl(evolvingArrayTemplateLiterals1.ts, 0, 0)) + +arr3.push(`vegetable_${v3}`); +>arr3.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>arr3 : Symbol(arr3, Decl(evolvingArrayTemplateLiterals1.ts, 12, 5)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>v3 : Symbol(v3, Decl(evolvingArrayTemplateLiterals1.ts, 13, 5)) + +arr3; +>arr3 : Symbol(arr3, Decl(evolvingArrayTemplateLiterals1.ts, 12, 5)) + +const arr4 = []; +>arr4 : Symbol(arr4, Decl(evolvingArrayTemplateLiterals1.ts, 17, 5)) + +declare const v4: Vegetable; +>v4 : Symbol(v4, Decl(evolvingArrayTemplateLiterals1.ts, 18, 13)) +>Vegetable : Symbol(Vegetable, Decl(evolvingArrayTemplateLiterals1.ts, 0, 0)) + +arr4.push(`vegetable_${v4}`); +>arr4.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>arr4 : Symbol(arr4, Decl(evolvingArrayTemplateLiterals1.ts, 17, 5)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>v4 : Symbol(v4, Decl(evolvingArrayTemplateLiterals1.ts, 18, 13)) + +arr4; +>arr4 : Symbol(arr4, Decl(evolvingArrayTemplateLiterals1.ts, 17, 5)) + diff --git a/tests/baselines/reference/evolvingArrayTemplateLiterals1.types b/tests/baselines/reference/evolvingArrayTemplateLiterals1.types new file mode 100644 index 0000000000000..e6cb5e5e92e57 --- /dev/null +++ b/tests/baselines/reference/evolvingArrayTemplateLiterals1.types @@ -0,0 +1,125 @@ +//// [tests/cases/compiler/evolvingArrayTemplateLiterals1.ts] //// + +=== evolvingArrayTemplateLiterals1.ts === +type Vegetable = "spinach" | "carrot"; +>Vegetable : Vegetable +> : ^^^^^^^^^ + +const arr1 = []; +>arr1 : any[] +> : ^^^^^ +>[] : never[] +> : ^^^^^^^ + +const v1 = "carrot"; +>v1 : "carrot" +> : ^^^^^^^^ +>"carrot" : "carrot" +> : ^^^^^^^^ + +arr1.push(`vegetable_${v1}`); +>arr1.push(`vegetable_${v1}`) : number +> : ^^^^^^ +>arr1.push : (...items: any[]) => number +> : ^^^^ ^^^^^^^^^^^^ +>arr1 : any[] +> : ^^^^^ +>push : (...items: any[]) => number +> : ^^^^ ^^^^^^^^^^^^ +>`vegetable_${v1}` : "vegetable_carrot" +> : ^^^^^^^^^^^^^^^^^^ +>v1 : "carrot" +> : ^^^^^^^^ + +arr1; +>arr1 : string[] +> : ^^^^^^^^ + +const arr2 = []; +>arr2 : any[] +> : ^^^^^ +>[] : never[] +> : ^^^^^^^ + +const v2: "carrot" = "carrot"; +>v2 : "carrot" +> : ^^^^^^^^ +>"carrot" : "carrot" +> : ^^^^^^^^ + +arr2.push(`vegetable_${v2}`); +>arr2.push(`vegetable_${v2}`) : number +> : ^^^^^^ +>arr2.push : (...items: any[]) => number +> : ^^^^ ^^^^^^^^^^^^ +>arr2 : any[] +> : ^^^^^ +>push : (...items: any[]) => number +> : ^^^^ ^^^^^^^^^^^^ +>`vegetable_${v2}` : string +> : ^^^^^^ +>v2 : "carrot" +> : ^^^^^^^^ + +arr2; +>arr2 : string[] +> : ^^^^^^^^ + +const arr3 = []; +>arr3 : any[] +> : ^^^^^ +>[] : never[] +> : ^^^^^^^ + +const v3: Vegetable = "carrot"; +>v3 : Vegetable +> : ^^^^^^^^^ +>"carrot" : "carrot" +> : ^^^^^^^^ + +arr3.push(`vegetable_${v3}`); +>arr3.push(`vegetable_${v3}`) : number +> : ^^^^^^ +>arr3.push : (...items: any[]) => number +> : ^^^^ ^^^^^^^^^^^^ +>arr3 : any[] +> : ^^^^^ +>push : (...items: any[]) => number +> : ^^^^ ^^^^^^^^^^^^ +>`vegetable_${v3}` : string +> : ^^^^^^ +>v3 : "carrot" +> : ^^^^^^^^ + +arr3; +>arr3 : string[] +> : ^^^^^^^^ + +const arr4 = []; +>arr4 : any[] +> : ^^^^^ +>[] : never[] +> : ^^^^^^^ + +declare const v4: Vegetable; +>v4 : Vegetable +> : ^^^^^^^^^ + +arr4.push(`vegetable_${v4}`); +>arr4.push(`vegetable_${v4}`) : number +> : ^^^^^^ +>arr4.push : (...items: any[]) => number +> : ^^^^ ^^^^^^^^^^^^ +>arr4 : any[] +> : ^^^^^ +>push : (...items: any[]) => number +> : ^^^^ ^^^^^^^^^^^^ +>`vegetable_${v4}` : string +> : ^^^^^^ +>v4 : Vegetable +> : ^^^^^^^^^ + +arr4; +>arr4 : string[] +> : ^^^^^^^^ + diff --git a/tests/baselines/reference/templateLiteralConstantEvaluation.symbols b/tests/baselines/reference/templateLiteralConstantEvaluation.symbols index 5a99b099db153..a249281df72e6 100644 --- a/tests/baselines/reference/templateLiteralConstantEvaluation.symbols +++ b/tests/baselines/reference/templateLiteralConstantEvaluation.symbols @@ -34,3 +34,10 @@ fn(`${b} 3`); >fn : Symbol(fn, Decl(templateLiteralConstantEvaluation.ts, 0, 0)) >b : Symbol(b, Decl(templateLiteralConstantEvaluation.ts, 7, 5)) +const empty = ""; +>empty : Symbol(empty, Decl(templateLiteralConstantEvaluation.ts, 13, 5)) + +const empty2 = `${empty}`; +>empty2 : Symbol(empty2, Decl(templateLiteralConstantEvaluation.ts, 14, 5)) +>empty : Symbol(empty, Decl(templateLiteralConstantEvaluation.ts, 13, 5)) + diff --git a/tests/baselines/reference/templateLiteralConstantEvaluation.types b/tests/baselines/reference/templateLiteralConstantEvaluation.types index fa84571697298..84b470cccf620 100644 --- a/tests/baselines/reference/templateLiteralConstantEvaluation.types +++ b/tests/baselines/reference/templateLiteralConstantEvaluation.types @@ -58,3 +58,17 @@ fn(`${b} 3`); >b : string > : ^^^^^^ +const empty = ""; +>empty : "" +> : ^^ +>"" : "" +> : ^^ + +const empty2 = `${empty}`; +>empty2 : "" +> : ^^ +>`${empty}` : "" +> : ^^ +>empty : "" +> : ^^ + diff --git a/tests/baselines/reference/templateLiteralTypes9.errors.txt b/tests/baselines/reference/templateLiteralTypes9.errors.txt new file mode 100644 index 0000000000000..d8b777a3922fd --- /dev/null +++ b/tests/baselines/reference/templateLiteralTypes9.errors.txt @@ -0,0 +1,32 @@ +templateLiteralTypes9.ts(19,3): error TS2322: Type '`${string}_BAZ`' is not assignable to type '`${string}_FOO` | `${string}_BAR`'. +templateLiteralTypes9.ts(20,8): error TS7006: Parameter 'arg' implicitly has an 'any' type. + + +==== templateLiteralTypes9.ts (2 errors) ==== + type Target = + | { type: `${string}_FOO`; cb: (arg: number) => void } + | { type: `${string}_BAR`; cb: (arg: string) => void }; + + declare const str: string; + + const obj1: Target = { + type: `${str}_FOO`, + cb: (arg) => {}, + }; + + const obj2: Target = { + type: `${str}_BAR`, + cb: (arg) => {}, + }; + + // error + const obj3: Target = { + type: `${str}_BAZ`, + ~~~~ +!!! error TS2322: Type '`${string}_BAZ`' is not assignable to type '`${string}_FOO` | `${string}_BAR`'. +!!! related TS6500 templateLiteralTypes9.ts:2:7: The expected type comes from property 'type' which is declared here on type 'Target' + cb: (arg) => {}, + ~~~ +!!! error TS7006: Parameter 'arg' implicitly has an 'any' type. + }; + \ No newline at end of file diff --git a/tests/baselines/reference/templateLiteralTypes9.symbols b/tests/baselines/reference/templateLiteralTypes9.symbols new file mode 100644 index 0000000000000..1e2b24ee41f39 --- /dev/null +++ b/tests/baselines/reference/templateLiteralTypes9.symbols @@ -0,0 +1,62 @@ +//// [tests/cases/conformance/types/literal/templateLiteralTypes9.ts] //// + +=== templateLiteralTypes9.ts === +type Target = +>Target : Symbol(Target, Decl(templateLiteralTypes9.ts, 0, 0)) + + | { type: `${string}_FOO`; cb: (arg: number) => void } +>type : Symbol(type, Decl(templateLiteralTypes9.ts, 1, 5)) +>cb : Symbol(cb, Decl(templateLiteralTypes9.ts, 1, 28)) +>arg : Symbol(arg, Decl(templateLiteralTypes9.ts, 1, 34)) + + | { type: `${string}_BAR`; cb: (arg: string) => void }; +>type : Symbol(type, Decl(templateLiteralTypes9.ts, 2, 5)) +>cb : Symbol(cb, Decl(templateLiteralTypes9.ts, 2, 28)) +>arg : Symbol(arg, Decl(templateLiteralTypes9.ts, 2, 34)) + +declare const str: string; +>str : Symbol(str, Decl(templateLiteralTypes9.ts, 4, 13)) + +const obj1: Target = { +>obj1 : Symbol(obj1, Decl(templateLiteralTypes9.ts, 6, 5)) +>Target : Symbol(Target, Decl(templateLiteralTypes9.ts, 0, 0)) + + type: `${str}_FOO`, +>type : Symbol(type, Decl(templateLiteralTypes9.ts, 6, 22)) +>str : Symbol(str, Decl(templateLiteralTypes9.ts, 4, 13)) + + cb: (arg) => {}, +>cb : Symbol(cb, Decl(templateLiteralTypes9.ts, 7, 21)) +>arg : Symbol(arg, Decl(templateLiteralTypes9.ts, 8, 7)) + +}; + +const obj2: Target = { +>obj2 : Symbol(obj2, Decl(templateLiteralTypes9.ts, 11, 5)) +>Target : Symbol(Target, Decl(templateLiteralTypes9.ts, 0, 0)) + + type: `${str}_BAR`, +>type : Symbol(type, Decl(templateLiteralTypes9.ts, 11, 22)) +>str : Symbol(str, Decl(templateLiteralTypes9.ts, 4, 13)) + + cb: (arg) => {}, +>cb : Symbol(cb, Decl(templateLiteralTypes9.ts, 12, 21)) +>arg : Symbol(arg, Decl(templateLiteralTypes9.ts, 13, 7)) + +}; + +// error +const obj3: Target = { +>obj3 : Symbol(obj3, Decl(templateLiteralTypes9.ts, 17, 5)) +>Target : Symbol(Target, Decl(templateLiteralTypes9.ts, 0, 0)) + + type: `${str}_BAZ`, +>type : Symbol(type, Decl(templateLiteralTypes9.ts, 17, 22)) +>str : Symbol(str, Decl(templateLiteralTypes9.ts, 4, 13)) + + cb: (arg) => {}, +>cb : Symbol(cb, Decl(templateLiteralTypes9.ts, 18, 21)) +>arg : Symbol(arg, Decl(templateLiteralTypes9.ts, 19, 7)) + +}; + diff --git a/tests/baselines/reference/templateLiteralTypes9.types b/tests/baselines/reference/templateLiteralTypes9.types new file mode 100644 index 0000000000000..847b43d8a0e4b --- /dev/null +++ b/tests/baselines/reference/templateLiteralTypes9.types @@ -0,0 +1,100 @@ +//// [tests/cases/conformance/types/literal/templateLiteralTypes9.ts] //// + +=== templateLiteralTypes9.ts === +type Target = +>Target : Target +> : ^^^^^^ + + | { type: `${string}_FOO`; cb: (arg: number) => void } +>type : `${string}_FOO` +> : ^^^^^^^^^^^^^^^ +>cb : (arg: number) => void +> : ^ ^^ ^^^^^ +>arg : number +> : ^^^^^^ + + | { type: `${string}_BAR`; cb: (arg: string) => void }; +>type : `${string}_BAR` +> : ^^^^^^^^^^^^^^^ +>cb : (arg: string) => void +> : ^ ^^ ^^^^^ +>arg : string +> : ^^^^^^ + +declare const str: string; +>str : string +> : ^^^^^^ + +const obj1: Target = { +>obj1 : Target +> : ^^^^^^ +>{ type: `${str}_FOO`, cb: (arg) => {},} : { type: `${string}_FOO`; cb: (arg: number) => void; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^ + + type: `${str}_FOO`, +>type : `${string}_FOO` +> : ^^^^^^^^^^^^^^^ +>`${str}_FOO` : `${string}_FOO` +> : ^^^^^^^^^^^^^^^ +>str : string +> : ^^^^^^ + + cb: (arg) => {}, +>cb : (arg: number) => void +> : ^ ^^^^^^^^^^^^^^^^^ +>(arg) => {} : (arg: number) => void +> : ^ ^^^^^^^^^^^^^^^^^ +>arg : number +> : ^^^^^^ + +}; + +const obj2: Target = { +>obj2 : Target +> : ^^^^^^ +>{ type: `${str}_BAR`, cb: (arg) => {},} : { type: `${string}_BAR`; cb: (arg: string) => void; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^ + + type: `${str}_BAR`, +>type : `${string}_BAR` +> : ^^^^^^^^^^^^^^^ +>`${str}_BAR` : `${string}_BAR` +> : ^^^^^^^^^^^^^^^ +>str : string +> : ^^^^^^ + + cb: (arg) => {}, +>cb : (arg: string) => void +> : ^ ^^^^^^^^^^^^^^^^^ +>(arg) => {} : (arg: string) => void +> : ^ ^^^^^^^^^^^^^^^^^ +>arg : string +> : ^^^^^^ + +}; + +// error +const obj3: Target = { +>obj3 : Target +> : ^^^^^^ +>{ type: `${str}_BAZ`, cb: (arg) => {},} : { type: `${string}_BAZ`; cb: (arg: any) => void; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ + + type: `${str}_BAZ`, +>type : `${string}_BAZ` +> : ^^^^^^^^^^^^^^^ +>`${str}_BAZ` : `${string}_BAZ` +> : ^^^^^^^^^^^^^^^ +>str : string +> : ^^^^^^ + + cb: (arg) => {}, +>cb : (arg: any) => void +> : ^ ^^^^^^^^^^^^^^ +>(arg) => {} : (arg: any) => void +> : ^ ^^^^^^^^^^^^^^ +>arg : any +> : ^^^ + +}; + diff --git a/tests/cases/compiler/discriminantUsingEvaluatableTemplateExpression.ts b/tests/cases/compiler/discriminantUsingEvaluatableTemplateExpression.ts index 17c0be879ebc6..87fb8048dcfd3 100644 --- a/tests/cases/compiler/discriminantUsingEvaluatableTemplateExpression.ts +++ b/tests/cases/compiler/discriminantUsingEvaluatableTemplateExpression.ts @@ -14,3 +14,13 @@ foo({ x; // string }, }); + +type E1 = { d: "main1-sub1"; cb: (x: string) => void }; +type E2 = { d: "main2-sub2"; cb: (x: number) => void }; + +declare function bar(_: E1 | E2): void; + +const someCategory = "main1"; +const someSubcategory = "sub1"; + +bar({ d: `${someCategory}-${someSubcategory}`, cb: (x) => {} }); diff --git a/tests/cases/compiler/evolvingArrayTemplateLiterals1.ts b/tests/cases/compiler/evolvingArrayTemplateLiterals1.ts new file mode 100644 index 0000000000000..4d29b4b47fb45 --- /dev/null +++ b/tests/cases/compiler/evolvingArrayTemplateLiterals1.ts @@ -0,0 +1,24 @@ +// @strict: true +// @noEmit: true + +type Vegetable = "spinach" | "carrot"; + +const arr1 = []; +const v1 = "carrot"; +arr1.push(`vegetable_${v1}`); +arr1; + +const arr2 = []; +const v2: "carrot" = "carrot"; +arr2.push(`vegetable_${v2}`); +arr2; + +const arr3 = []; +const v3: Vegetable = "carrot"; +arr3.push(`vegetable_${v3}`); +arr3; + +const arr4 = []; +declare const v4: Vegetable; +arr4.push(`vegetable_${v4}`); +arr4; diff --git a/tests/cases/compiler/templateLiteralConstantEvaluation.ts b/tests/cases/compiler/templateLiteralConstantEvaluation.ts index 479e6dba827c9..c1335e65d5922 100644 --- a/tests/cases/compiler/templateLiteralConstantEvaluation.ts +++ b/tests/cases/compiler/templateLiteralConstantEvaluation.ts @@ -13,3 +13,6 @@ const c = `${b} 3`; const d = `${b} 3` as const; fn(`${b} 3`); + +const empty = ""; +const empty2 = `${empty}`; diff --git a/tests/cases/conformance/types/literal/templateLiteralTypes9.ts b/tests/cases/conformance/types/literal/templateLiteralTypes9.ts new file mode 100644 index 0000000000000..90340b83926b8 --- /dev/null +++ b/tests/cases/conformance/types/literal/templateLiteralTypes9.ts @@ -0,0 +1,24 @@ +// @strict: true +// @noEmit: true + +type Target = + | { type: `${string}_FOO`; cb: (arg: number) => void } + | { type: `${string}_BAR`; cb: (arg: string) => void }; + +declare const str: string; + +const obj1: Target = { + type: `${str}_FOO`, + cb: (arg) => {}, +}; + +const obj2: Target = { + type: `${str}_BAR`, + cb: (arg) => {}, +}; + +// error +const obj3: Target = { + type: `${str}_BAZ`, + cb: (arg) => {}, +}; diff --git a/tests/cases/conformance/types/union/discriminatedUnionTypesOverlappingDiscriminants1.ts b/tests/cases/conformance/types/union/discriminatedUnionTypesOverlappingDiscriminants1.ts new file mode 100644 index 0000000000000..cbe5954e72bb7 --- /dev/null +++ b/tests/cases/conformance/types/union/discriminatedUnionTypesOverlappingDiscriminants1.ts @@ -0,0 +1,137 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/57231 + +type Food = "apple" | "orange"; +type Vegetable = "spinach" | "carrot"; +type Other = "milk" | "water"; +type Custom = "air" | "soil"; + +type Target = + | { + audience: "earth"; + meal: + | Custom + | `fruit_${Food}` + | `vegetable_${Vegetable}` + | `other_${Other}`; + } + | { + audience: "mars" | "jupiter"; + meal: string; + }; + +const target1: Target = { + audience: "earth", + meal: `vegetable_carrot`, +}; + +const target2: Target = { + meal: `vegetable_carrot`, + audience: "earth", +}; + +const typedVegetableWithInitializer: Vegetable = 'carrot'; + +const target3: Target = { + audience: "earth", + meal: `vegetable_${typedVegetableWithInitializer}`, +}; + +const target4: Target = { + meal: `vegetable_${typedVegetableWithInitializer}`, + audience: "earth", +}; + +const typedCarrotWithInitializer: "carrot" = 'carrot'; + +const target5: Target = { + audience: "earth", + meal: `vegetable_${typedCarrotWithInitializer}`, +}; + +const target6: Target = { + meal: `vegetable_${typedCarrotWithInitializer}`, + audience: "earth", +}; + +const carrotInitializer = 'carrot'; + +const target7: Target = { + audience: "earth", + meal: `vegetable_${carrotInitializer}`, +}; + +const target8: Target = { + meal: `vegetable_${carrotInitializer}`, + audience: "earth", +}; + +declare const vegetable: Vegetable; + +const target9: Target = { + audience: "earth", + meal: `vegetable_${vegetable}`, +}; + +const target10: Target = { + meal: `vegetable_${vegetable}`, + audience: "earth", +}; + +const typedNonVegetableWithInitializer: "cow" | "pig" = "cow"; + +// error +const target11: Target = { + audience: "earth", + meal: `vegetable_${typedNonVegetableWithInitializer}`, +}; + +// error +const target12: Target = { + meal: `vegetable_${typedNonVegetableWithInitializer}`, + audience: "earth", +}; + +const typedCowWithInitializer: "cow" = "cow"; + +// error +const target13: Target = { + audience: "earth", + meal: `vegetable_${typedCowWithInitializer}`, +}; + +// error +const target14: Target = { + meal: `vegetable_${typedCowWithInitializer}`, + audience: "earth", +}; + +const cowInitializer = "cow"; + +// error +const target15: Target = { + audience: "earth", + meal: `vegetable_${cowInitializer}`, +}; + +// error +const target16: Target = { + meal: `vegetable_${cowInitializer}`, + audience: "earth", +}; + +declare const nonVegetable: "cow" | "pig"; + +// error +const target17: Target = { + audience: "earth", + meal: `vegetable_${nonVegetable}`, +}; + +// error +const target18: Target = { + meal: `vegetable_${nonVegetable}`, + audience: "earth", +};