mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-07 12:25:09 -05:00
Check if switch statements are exhaustive when their expressions is generic with a literal type constraint (#60644)
This commit is contained in:
committed by
GitHub
parent
97177722b8
commit
14c65b3119
@@ -38682,7 +38682,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// A missing not-equal flag indicates that the type wasn't handled by some case.
|
||||
return !someType(operandConstraint, t => getTypeFacts(t, notEqualFacts) === notEqualFacts);
|
||||
}
|
||||
const type = checkExpressionCached(node.expression);
|
||||
const type = getBaseConstraintOrType(checkExpressionCached(node.expression));
|
||||
if (!isLiteralType(type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
71
tests/baselines/reference/dependentReturnType9.errors.txt
Normal file
71
tests/baselines/reference/dependentReturnType9.errors.txt
Normal file
@@ -0,0 +1,71 @@
|
||||
dependentReturnType9.ts(57,4): error TS2366: Function lacks ending return statement and return type does not include 'undefined'.
|
||||
|
||||
|
||||
==== dependentReturnType9.ts (1 errors) ====
|
||||
type Payload =
|
||||
| { _tag: "auth"; username: string; password: string }
|
||||
| { _tag: "cart"; items: Array<{ id: string; quantity: number }> }
|
||||
| { _tag: "person"; name: string; age: number };
|
||||
|
||||
type PayloadContent = {
|
||||
[P in Payload as P["_tag"]]: Omit<P, "_tag">;
|
||||
};
|
||||
|
||||
// ok, exhaustive cases and default case with throw
|
||||
function mockPayload<P_TAG extends Payload["_tag"]>(
|
||||
str: P_TAG,
|
||||
): PayloadContent[P_TAG] {
|
||||
switch (str) {
|
||||
case "auth":
|
||||
return { username: "test", password: "admin" };
|
||||
case "cart":
|
||||
return { items: [{ id: "123", quantity: 123 }] };
|
||||
case "person":
|
||||
return { name: "andrea", age: 27 };
|
||||
default:
|
||||
throw new Error("unknown tag");
|
||||
}
|
||||
}
|
||||
|
||||
// ok, non-exhaustive cases but default case with throw
|
||||
function mockPayload2<P_TAG extends Payload["_tag"]>(
|
||||
str: P_TAG,
|
||||
): PayloadContent[P_TAG] {
|
||||
switch (str) {
|
||||
case "auth":
|
||||
return { username: "test", password: "admin" };
|
||||
case "cart":
|
||||
return { items: [{ id: "123", quantity: 123 }] };
|
||||
default:
|
||||
throw new Error("unhandled tag");
|
||||
}
|
||||
}
|
||||
|
||||
// ok, exhaustive cases
|
||||
function mockPayload3<P_TAG extends Payload["_tag"]>(
|
||||
str: P_TAG,
|
||||
): PayloadContent[P_TAG] {
|
||||
switch (str) {
|
||||
case "auth":
|
||||
return { username: "test", password: "admin" };
|
||||
case "cart":
|
||||
return { items: [{ id: "123", quantity: 123 }] };
|
||||
case "person":
|
||||
return { name: "andrea", age: 27 };
|
||||
}
|
||||
}
|
||||
|
||||
// error, non-exhaustive cases
|
||||
function mockPayload4<P_TAG extends Payload["_tag"]>(
|
||||
str: P_TAG,
|
||||
): PayloadContent[P_TAG] {
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2366: Function lacks ending return statement and return type does not include 'undefined'.
|
||||
switch (str) {
|
||||
case "auth":
|
||||
return { username: "test", password: "admin" };
|
||||
case "cart":
|
||||
return { items: [{ id: "123", quantity: 123 }] };
|
||||
}
|
||||
}
|
||||
|
||||
173
tests/baselines/reference/dependentReturnType9.symbols
Normal file
173
tests/baselines/reference/dependentReturnType9.symbols
Normal file
@@ -0,0 +1,173 @@
|
||||
//// [tests/cases/compiler/dependentReturnType9.ts] ////
|
||||
|
||||
=== dependentReturnType9.ts ===
|
||||
type Payload =
|
||||
>Payload : Symbol(Payload, Decl(dependentReturnType9.ts, 0, 0))
|
||||
|
||||
| { _tag: "auth"; username: string; password: string }
|
||||
>_tag : Symbol(_tag, Decl(dependentReturnType9.ts, 1, 5))
|
||||
>username : Symbol(username, Decl(dependentReturnType9.ts, 1, 19))
|
||||
>password : Symbol(password, Decl(dependentReturnType9.ts, 1, 37))
|
||||
|
||||
| { _tag: "cart"; items: Array<{ id: string; quantity: number }> }
|
||||
>_tag : Symbol(_tag, Decl(dependentReturnType9.ts, 2, 5))
|
||||
>items : Symbol(items, Decl(dependentReturnType9.ts, 2, 19))
|
||||
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>id : Symbol(id, Decl(dependentReturnType9.ts, 2, 34))
|
||||
>quantity : Symbol(quantity, Decl(dependentReturnType9.ts, 2, 46))
|
||||
|
||||
| { _tag: "person"; name: string; age: number };
|
||||
>_tag : Symbol(_tag, Decl(dependentReturnType9.ts, 3, 5))
|
||||
>name : Symbol(name, Decl(dependentReturnType9.ts, 3, 21))
|
||||
>age : Symbol(age, Decl(dependentReturnType9.ts, 3, 35))
|
||||
|
||||
type PayloadContent = {
|
||||
>PayloadContent : Symbol(PayloadContent, Decl(dependentReturnType9.ts, 3, 50))
|
||||
|
||||
[P in Payload as P["_tag"]]: Omit<P, "_tag">;
|
||||
>P : Symbol(P, Decl(dependentReturnType9.ts, 6, 3))
|
||||
>Payload : Symbol(Payload, Decl(dependentReturnType9.ts, 0, 0))
|
||||
>P : Symbol(P, Decl(dependentReturnType9.ts, 6, 3))
|
||||
>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --))
|
||||
>P : Symbol(P, Decl(dependentReturnType9.ts, 6, 3))
|
||||
|
||||
};
|
||||
|
||||
// ok, exhaustive cases and default case with throw
|
||||
function mockPayload<P_TAG extends Payload["_tag"]>(
|
||||
>mockPayload : Symbol(mockPayload, Decl(dependentReturnType9.ts, 7, 2))
|
||||
>P_TAG : Symbol(P_TAG, Decl(dependentReturnType9.ts, 10, 21))
|
||||
>Payload : Symbol(Payload, Decl(dependentReturnType9.ts, 0, 0))
|
||||
|
||||
str: P_TAG,
|
||||
>str : Symbol(str, Decl(dependentReturnType9.ts, 10, 52))
|
||||
>P_TAG : Symbol(P_TAG, Decl(dependentReturnType9.ts, 10, 21))
|
||||
|
||||
): PayloadContent[P_TAG] {
|
||||
>PayloadContent : Symbol(PayloadContent, Decl(dependentReturnType9.ts, 3, 50))
|
||||
>P_TAG : Symbol(P_TAG, Decl(dependentReturnType9.ts, 10, 21))
|
||||
|
||||
switch (str) {
|
||||
>str : Symbol(str, Decl(dependentReturnType9.ts, 10, 52))
|
||||
|
||||
case "auth":
|
||||
return { username: "test", password: "admin" };
|
||||
>username : Symbol(username, Decl(dependentReturnType9.ts, 15, 14))
|
||||
>password : Symbol(password, Decl(dependentReturnType9.ts, 15, 32))
|
||||
|
||||
case "cart":
|
||||
return { items: [{ id: "123", quantity: 123 }] };
|
||||
>items : Symbol(items, Decl(dependentReturnType9.ts, 17, 14))
|
||||
>id : Symbol(id, Decl(dependentReturnType9.ts, 17, 24))
|
||||
>quantity : Symbol(quantity, Decl(dependentReturnType9.ts, 17, 35))
|
||||
|
||||
case "person":
|
||||
return { name: "andrea", age: 27 };
|
||||
>name : Symbol(name, Decl(dependentReturnType9.ts, 19, 14))
|
||||
>age : Symbol(age, Decl(dependentReturnType9.ts, 19, 30))
|
||||
|
||||
default:
|
||||
throw new Error("unknown tag");
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
}
|
||||
|
||||
// ok, non-exhaustive cases but default case with throw
|
||||
function mockPayload2<P_TAG extends Payload["_tag"]>(
|
||||
>mockPayload2 : Symbol(mockPayload2, Decl(dependentReturnType9.ts, 23, 1))
|
||||
>P_TAG : Symbol(P_TAG, Decl(dependentReturnType9.ts, 26, 22))
|
||||
>Payload : Symbol(Payload, Decl(dependentReturnType9.ts, 0, 0))
|
||||
|
||||
str: P_TAG,
|
||||
>str : Symbol(str, Decl(dependentReturnType9.ts, 26, 53))
|
||||
>P_TAG : Symbol(P_TAG, Decl(dependentReturnType9.ts, 26, 22))
|
||||
|
||||
): PayloadContent[P_TAG] {
|
||||
>PayloadContent : Symbol(PayloadContent, Decl(dependentReturnType9.ts, 3, 50))
|
||||
>P_TAG : Symbol(P_TAG, Decl(dependentReturnType9.ts, 26, 22))
|
||||
|
||||
switch (str) {
|
||||
>str : Symbol(str, Decl(dependentReturnType9.ts, 26, 53))
|
||||
|
||||
case "auth":
|
||||
return { username: "test", password: "admin" };
|
||||
>username : Symbol(username, Decl(dependentReturnType9.ts, 31, 14))
|
||||
>password : Symbol(password, Decl(dependentReturnType9.ts, 31, 32))
|
||||
|
||||
case "cart":
|
||||
return { items: [{ id: "123", quantity: 123 }] };
|
||||
>items : Symbol(items, Decl(dependentReturnType9.ts, 33, 14))
|
||||
>id : Symbol(id, Decl(dependentReturnType9.ts, 33, 24))
|
||||
>quantity : Symbol(quantity, Decl(dependentReturnType9.ts, 33, 35))
|
||||
|
||||
default:
|
||||
throw new Error("unhandled tag");
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
}
|
||||
}
|
||||
|
||||
// ok, exhaustive cases
|
||||
function mockPayload3<P_TAG extends Payload["_tag"]>(
|
||||
>mockPayload3 : Symbol(mockPayload3, Decl(dependentReturnType9.ts, 37, 1))
|
||||
>P_TAG : Symbol(P_TAG, Decl(dependentReturnType9.ts, 40, 22))
|
||||
>Payload : Symbol(Payload, Decl(dependentReturnType9.ts, 0, 0))
|
||||
|
||||
str: P_TAG,
|
||||
>str : Symbol(str, Decl(dependentReturnType9.ts, 40, 53))
|
||||
>P_TAG : Symbol(P_TAG, Decl(dependentReturnType9.ts, 40, 22))
|
||||
|
||||
): PayloadContent[P_TAG] {
|
||||
>PayloadContent : Symbol(PayloadContent, Decl(dependentReturnType9.ts, 3, 50))
|
||||
>P_TAG : Symbol(P_TAG, Decl(dependentReturnType9.ts, 40, 22))
|
||||
|
||||
switch (str) {
|
||||
>str : Symbol(str, Decl(dependentReturnType9.ts, 40, 53))
|
||||
|
||||
case "auth":
|
||||
return { username: "test", password: "admin" };
|
||||
>username : Symbol(username, Decl(dependentReturnType9.ts, 45, 14))
|
||||
>password : Symbol(password, Decl(dependentReturnType9.ts, 45, 32))
|
||||
|
||||
case "cart":
|
||||
return { items: [{ id: "123", quantity: 123 }] };
|
||||
>items : Symbol(items, Decl(dependentReturnType9.ts, 47, 14))
|
||||
>id : Symbol(id, Decl(dependentReturnType9.ts, 47, 24))
|
||||
>quantity : Symbol(quantity, Decl(dependentReturnType9.ts, 47, 35))
|
||||
|
||||
case "person":
|
||||
return { name: "andrea", age: 27 };
|
||||
>name : Symbol(name, Decl(dependentReturnType9.ts, 49, 14))
|
||||
>age : Symbol(age, Decl(dependentReturnType9.ts, 49, 30))
|
||||
}
|
||||
}
|
||||
|
||||
// error, non-exhaustive cases
|
||||
function mockPayload4<P_TAG extends Payload["_tag"]>(
|
||||
>mockPayload4 : Symbol(mockPayload4, Decl(dependentReturnType9.ts, 51, 1))
|
||||
>P_TAG : Symbol(P_TAG, Decl(dependentReturnType9.ts, 54, 22))
|
||||
>Payload : Symbol(Payload, Decl(dependentReturnType9.ts, 0, 0))
|
||||
|
||||
str: P_TAG,
|
||||
>str : Symbol(str, Decl(dependentReturnType9.ts, 54, 53))
|
||||
>P_TAG : Symbol(P_TAG, Decl(dependentReturnType9.ts, 54, 22))
|
||||
|
||||
): PayloadContent[P_TAG] {
|
||||
>PayloadContent : Symbol(PayloadContent, Decl(dependentReturnType9.ts, 3, 50))
|
||||
>P_TAG : Symbol(P_TAG, Decl(dependentReturnType9.ts, 54, 22))
|
||||
|
||||
switch (str) {
|
||||
>str : Symbol(str, Decl(dependentReturnType9.ts, 54, 53))
|
||||
|
||||
case "auth":
|
||||
return { username: "test", password: "admin" };
|
||||
>username : Symbol(username, Decl(dependentReturnType9.ts, 59, 14))
|
||||
>password : Symbol(password, Decl(dependentReturnType9.ts, 59, 32))
|
||||
|
||||
case "cart":
|
||||
return { items: [{ id: "123", quantity: 123 }] };
|
||||
>items : Symbol(items, Decl(dependentReturnType9.ts, 61, 14))
|
||||
>id : Symbol(id, Decl(dependentReturnType9.ts, 61, 24))
|
||||
>quantity : Symbol(quantity, Decl(dependentReturnType9.ts, 61, 35))
|
||||
}
|
||||
}
|
||||
|
||||
306
tests/baselines/reference/dependentReturnType9.types
Normal file
306
tests/baselines/reference/dependentReturnType9.types
Normal file
@@ -0,0 +1,306 @@
|
||||
//// [tests/cases/compiler/dependentReturnType9.ts] ////
|
||||
|
||||
=== dependentReturnType9.ts ===
|
||||
type Payload =
|
||||
>Payload : Payload
|
||||
> : ^^^^^^^
|
||||
|
||||
| { _tag: "auth"; username: string; password: string }
|
||||
>_tag : "auth"
|
||||
> : ^^^^^^
|
||||
>username : string
|
||||
> : ^^^^^^
|
||||
>password : string
|
||||
> : ^^^^^^
|
||||
|
||||
| { _tag: "cart"; items: Array<{ id: string; quantity: number }> }
|
||||
>_tag : "cart"
|
||||
> : ^^^^^^
|
||||
>items : { id: string; quantity: number; }[]
|
||||
> : ^^^^^^ ^^^^^^^^^^^^ ^^^^^
|
||||
>id : string
|
||||
> : ^^^^^^
|
||||
>quantity : number
|
||||
> : ^^^^^^
|
||||
|
||||
| { _tag: "person"; name: string; age: number };
|
||||
>_tag : "person"
|
||||
> : ^^^^^^^^
|
||||
>name : string
|
||||
> : ^^^^^^
|
||||
>age : number
|
||||
> : ^^^^^^
|
||||
|
||||
type PayloadContent = {
|
||||
>PayloadContent : PayloadContent
|
||||
> : ^^^^^^^^^^^^^^
|
||||
|
||||
[P in Payload as P["_tag"]]: Omit<P, "_tag">;
|
||||
};
|
||||
|
||||
// ok, exhaustive cases and default case with throw
|
||||
function mockPayload<P_TAG extends Payload["_tag"]>(
|
||||
>mockPayload : <P_TAG extends Payload["_tag"]>(str: P_TAG) => PayloadContent[P_TAG]
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
|
||||
|
||||
str: P_TAG,
|
||||
>str : P_TAG
|
||||
> : ^^^^^
|
||||
|
||||
): PayloadContent[P_TAG] {
|
||||
switch (str) {
|
||||
>str : P_TAG
|
||||
> : ^^^^^
|
||||
|
||||
case "auth":
|
||||
>"auth" : "auth"
|
||||
> : ^^^^^^
|
||||
|
||||
return { username: "test", password: "admin" };
|
||||
>{ username: "test", password: "admin" } : { username: string; password: string; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>username : string
|
||||
> : ^^^^^^
|
||||
>"test" : "test"
|
||||
> : ^^^^^^
|
||||
>password : string
|
||||
> : ^^^^^^
|
||||
>"admin" : "admin"
|
||||
> : ^^^^^^^
|
||||
|
||||
case "cart":
|
||||
>"cart" : "cart"
|
||||
> : ^^^^^^
|
||||
|
||||
return { items: [{ id: "123", quantity: 123 }] };
|
||||
>{ items: [{ id: "123", quantity: 123 }] } : { items: { id: string; quantity: number; }[]; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>items : { id: string; quantity: number; }[]
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>[{ id: "123", quantity: 123 }] : { id: string; quantity: number; }[]
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>{ id: "123", quantity: 123 } : { id: string; quantity: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>id : string
|
||||
> : ^^^^^^
|
||||
>"123" : "123"
|
||||
> : ^^^^^
|
||||
>quantity : number
|
||||
> : ^^^^^^
|
||||
>123 : 123
|
||||
> : ^^^
|
||||
|
||||
case "person":
|
||||
>"person" : "person"
|
||||
> : ^^^^^^^^
|
||||
|
||||
return { name: "andrea", age: 27 };
|
||||
>{ name: "andrea", age: 27 } : { name: string; age: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>name : string
|
||||
> : ^^^^^^
|
||||
>"andrea" : "andrea"
|
||||
> : ^^^^^^^^
|
||||
>age : number
|
||||
> : ^^^^^^
|
||||
>27 : 27
|
||||
> : ^^
|
||||
|
||||
default:
|
||||
throw new Error("unknown tag");
|
||||
>new Error("unknown tag") : Error
|
||||
> : ^^^^^
|
||||
>Error : ErrorConstructor
|
||||
> : ^^^^^^^^^^^^^^^^
|
||||
>"unknown tag" : "unknown tag"
|
||||
> : ^^^^^^^^^^^^^
|
||||
}
|
||||
}
|
||||
|
||||
// ok, non-exhaustive cases but default case with throw
|
||||
function mockPayload2<P_TAG extends Payload["_tag"]>(
|
||||
>mockPayload2 : <P_TAG extends Payload["_tag"]>(str: P_TAG) => PayloadContent[P_TAG]
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
|
||||
|
||||
str: P_TAG,
|
||||
>str : P_TAG
|
||||
> : ^^^^^
|
||||
|
||||
): PayloadContent[P_TAG] {
|
||||
switch (str) {
|
||||
>str : P_TAG
|
||||
> : ^^^^^
|
||||
|
||||
case "auth":
|
||||
>"auth" : "auth"
|
||||
> : ^^^^^^
|
||||
|
||||
return { username: "test", password: "admin" };
|
||||
>{ username: "test", password: "admin" } : { username: string; password: string; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>username : string
|
||||
> : ^^^^^^
|
||||
>"test" : "test"
|
||||
> : ^^^^^^
|
||||
>password : string
|
||||
> : ^^^^^^
|
||||
>"admin" : "admin"
|
||||
> : ^^^^^^^
|
||||
|
||||
case "cart":
|
||||
>"cart" : "cart"
|
||||
> : ^^^^^^
|
||||
|
||||
return { items: [{ id: "123", quantity: 123 }] };
|
||||
>{ items: [{ id: "123", quantity: 123 }] } : { items: { id: string; quantity: number; }[]; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>items : { id: string; quantity: number; }[]
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>[{ id: "123", quantity: 123 }] : { id: string; quantity: number; }[]
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>{ id: "123", quantity: 123 } : { id: string; quantity: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>id : string
|
||||
> : ^^^^^^
|
||||
>"123" : "123"
|
||||
> : ^^^^^
|
||||
>quantity : number
|
||||
> : ^^^^^^
|
||||
>123 : 123
|
||||
> : ^^^
|
||||
|
||||
default:
|
||||
throw new Error("unhandled tag");
|
||||
>new Error("unhandled tag") : Error
|
||||
> : ^^^^^
|
||||
>Error : ErrorConstructor
|
||||
> : ^^^^^^^^^^^^^^^^
|
||||
>"unhandled tag" : "unhandled tag"
|
||||
> : ^^^^^^^^^^^^^^^
|
||||
}
|
||||
}
|
||||
|
||||
// ok, exhaustive cases
|
||||
function mockPayload3<P_TAG extends Payload["_tag"]>(
|
||||
>mockPayload3 : <P_TAG extends Payload["_tag"]>(str: P_TAG) => PayloadContent[P_TAG]
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
|
||||
|
||||
str: P_TAG,
|
||||
>str : P_TAG
|
||||
> : ^^^^^
|
||||
|
||||
): PayloadContent[P_TAG] {
|
||||
switch (str) {
|
||||
>str : P_TAG
|
||||
> : ^^^^^
|
||||
|
||||
case "auth":
|
||||
>"auth" : "auth"
|
||||
> : ^^^^^^
|
||||
|
||||
return { username: "test", password: "admin" };
|
||||
>{ username: "test", password: "admin" } : { username: string; password: string; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>username : string
|
||||
> : ^^^^^^
|
||||
>"test" : "test"
|
||||
> : ^^^^^^
|
||||
>password : string
|
||||
> : ^^^^^^
|
||||
>"admin" : "admin"
|
||||
> : ^^^^^^^
|
||||
|
||||
case "cart":
|
||||
>"cart" : "cart"
|
||||
> : ^^^^^^
|
||||
|
||||
return { items: [{ id: "123", quantity: 123 }] };
|
||||
>{ items: [{ id: "123", quantity: 123 }] } : { items: { id: string; quantity: number; }[]; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>items : { id: string; quantity: number; }[]
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>[{ id: "123", quantity: 123 }] : { id: string; quantity: number; }[]
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>{ id: "123", quantity: 123 } : { id: string; quantity: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>id : string
|
||||
> : ^^^^^^
|
||||
>"123" : "123"
|
||||
> : ^^^^^
|
||||
>quantity : number
|
||||
> : ^^^^^^
|
||||
>123 : 123
|
||||
> : ^^^
|
||||
|
||||
case "person":
|
||||
>"person" : "person"
|
||||
> : ^^^^^^^^
|
||||
|
||||
return { name: "andrea", age: 27 };
|
||||
>{ name: "andrea", age: 27 } : { name: string; age: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>name : string
|
||||
> : ^^^^^^
|
||||
>"andrea" : "andrea"
|
||||
> : ^^^^^^^^
|
||||
>age : number
|
||||
> : ^^^^^^
|
||||
>27 : 27
|
||||
> : ^^
|
||||
}
|
||||
}
|
||||
|
||||
// error, non-exhaustive cases
|
||||
function mockPayload4<P_TAG extends Payload["_tag"]>(
|
||||
>mockPayload4 : <P_TAG extends Payload["_tag"]>(str: P_TAG) => PayloadContent[P_TAG]
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
|
||||
|
||||
str: P_TAG,
|
||||
>str : P_TAG
|
||||
> : ^^^^^
|
||||
|
||||
): PayloadContent[P_TAG] {
|
||||
switch (str) {
|
||||
>str : P_TAG
|
||||
> : ^^^^^
|
||||
|
||||
case "auth":
|
||||
>"auth" : "auth"
|
||||
> : ^^^^^^
|
||||
|
||||
return { username: "test", password: "admin" };
|
||||
>{ username: "test", password: "admin" } : { username: string; password: string; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>username : string
|
||||
> : ^^^^^^
|
||||
>"test" : "test"
|
||||
> : ^^^^^^
|
||||
>password : string
|
||||
> : ^^^^^^
|
||||
>"admin" : "admin"
|
||||
> : ^^^^^^^
|
||||
|
||||
case "cart":
|
||||
>"cart" : "cart"
|
||||
> : ^^^^^^
|
||||
|
||||
return { items: [{ id: "123", quantity: 123 }] };
|
||||
>{ items: [{ id: "123", quantity: 123 }] } : { items: { id: string; quantity: number; }[]; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>items : { id: string; quantity: number; }[]
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>[{ id: "123", quantity: 123 }] : { id: string; quantity: number; }[]
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>{ id: "123", quantity: 123 } : { id: string; quantity: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>id : string
|
||||
> : ^^^^^^
|
||||
>"123" : "123"
|
||||
> : ^^^^^
|
||||
>quantity : number
|
||||
> : ^^^^^^
|
||||
>123 : 123
|
||||
> : ^^^
|
||||
}
|
||||
}
|
||||
|
||||
67
tests/cases/compiler/dependentReturnType9.ts
Normal file
67
tests/cases/compiler/dependentReturnType9.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
|
||||
type Payload =
|
||||
| { _tag: "auth"; username: string; password: string }
|
||||
| { _tag: "cart"; items: Array<{ id: string; quantity: number }> }
|
||||
| { _tag: "person"; name: string; age: number };
|
||||
|
||||
type PayloadContent = {
|
||||
[P in Payload as P["_tag"]]: Omit<P, "_tag">;
|
||||
};
|
||||
|
||||
// ok, exhaustive cases and default case with throw
|
||||
function mockPayload<P_TAG extends Payload["_tag"]>(
|
||||
str: P_TAG,
|
||||
): PayloadContent[P_TAG] {
|
||||
switch (str) {
|
||||
case "auth":
|
||||
return { username: "test", password: "admin" };
|
||||
case "cart":
|
||||
return { items: [{ id: "123", quantity: 123 }] };
|
||||
case "person":
|
||||
return { name: "andrea", age: 27 };
|
||||
default:
|
||||
throw new Error("unknown tag");
|
||||
}
|
||||
}
|
||||
|
||||
// ok, non-exhaustive cases but default case with throw
|
||||
function mockPayload2<P_TAG extends Payload["_tag"]>(
|
||||
str: P_TAG,
|
||||
): PayloadContent[P_TAG] {
|
||||
switch (str) {
|
||||
case "auth":
|
||||
return { username: "test", password: "admin" };
|
||||
case "cart":
|
||||
return { items: [{ id: "123", quantity: 123 }] };
|
||||
default:
|
||||
throw new Error("unhandled tag");
|
||||
}
|
||||
}
|
||||
|
||||
// ok, exhaustive cases
|
||||
function mockPayload3<P_TAG extends Payload["_tag"]>(
|
||||
str: P_TAG,
|
||||
): PayloadContent[P_TAG] {
|
||||
switch (str) {
|
||||
case "auth":
|
||||
return { username: "test", password: "admin" };
|
||||
case "cart":
|
||||
return { items: [{ id: "123", quantity: 123 }] };
|
||||
case "person":
|
||||
return { name: "andrea", age: 27 };
|
||||
}
|
||||
}
|
||||
|
||||
// error, non-exhaustive cases
|
||||
function mockPayload4<P_TAG extends Payload["_tag"]>(
|
||||
str: P_TAG,
|
||||
): PayloadContent[P_TAG] {
|
||||
switch (str) {
|
||||
case "auth":
|
||||
return { username: "test", password: "admin" };
|
||||
case "cart":
|
||||
return { items: [{ id: "123", quantity: 123 }] };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user