打字稿函数输出不能分配给条件类型
Typescript function output cannot be assigned to conditional type
我有一个更复杂问题的简化版本。以下导致 TSC 抛出错误:
type Demo<isTrue> = isTrue extends true ? { a: string } : isTrue extends false ? { b: string } : never;
const func = <T extends boolean>(arg: T): Demo<T> => {
if (arg) {
return {a: "hello" };
} else {
return { b: "world" };
}
};
const out = func(true);
抛出以下错误:
Type '{ a: string; }' is not assignable to type 'Demo<T>'.
Type '{ b: string; }' is not assignable to type 'Demo<T>'.
底部的out
经检查类型正确,所以只是函数定义有问题。我怎样才能更好地理解这个问题以及如何解决它?
我添加了重载和 Demo<boolean>
作为 return 类型。
在这种特殊情况下 T extends boolean
实际上与 Demo<boolean>
相同。
但请记住,泛型很棘手。 extends
不代表 equal
.
type Demo<isTrue> = isTrue extends true ? { a: string } : isTrue extends false ? { b: string } : never;
function func(arg: false): Demo<false>
function func(arg: true): Demo<true>
function func(arg: boolean): Demo<boolean> {
if (arg === true) {
const a = arg;
return { a: "hello" };
} else {
return { b: "world" };
}
};
const out = func(true);
How can I understand this better?
看看this GitHub thread (also see the original issue)。归结为 TypeScript 在使用条件类型时不支持缩小函数 return 类型。由于 Demo
类型的解析取决于泛型类型参数 T
,这与直接在 return 类型注释中编写条件相同。
如果我们重写 Demo
类型(仅用于演示目的),问题应该会变得更清楚:
type D<T extends boolean> = {
true: {
a: string
},
false: {
b: string
}
}[`${T}`];
const func = <T extends boolean>(arg: T): D<T> => {
if (arg) {
return {a: "hello" }; //Type '{ a: string; }' is not assignable to type '{ a: string; } & { b: string; }'
} else {
return { b: "world" }; //Type '{ b: string; }' is not assignable to type '{ a: string; } & { b: string; }'
}
};
现在应该 crystal 清楚 D<T>
仍未解决 直到 您为类型参数提供参数。这就是 const out = func(true);
被正确推断的原因。
How do I solve it?
您几乎只能使用 as Demo<T>
之类的类型断言,或者删除泛型类型参数并使用 答案中概述的重载重写签名。
我有一个更复杂问题的简化版本。以下导致 TSC 抛出错误:
type Demo<isTrue> = isTrue extends true ? { a: string } : isTrue extends false ? { b: string } : never;
const func = <T extends boolean>(arg: T): Demo<T> => {
if (arg) {
return {a: "hello" };
} else {
return { b: "world" };
}
};
const out = func(true);
抛出以下错误:
Type '{ a: string; }' is not assignable to type 'Demo<T>'.
Type '{ b: string; }' is not assignable to type 'Demo<T>'.
底部的out
经检查类型正确,所以只是函数定义有问题。我怎样才能更好地理解这个问题以及如何解决它?
我添加了重载和 Demo<boolean>
作为 return 类型。
在这种特殊情况下 T extends boolean
实际上与 Demo<boolean>
相同。
但请记住,泛型很棘手。 extends
不代表 equal
.
type Demo<isTrue> = isTrue extends true ? { a: string } : isTrue extends false ? { b: string } : never;
function func(arg: false): Demo<false>
function func(arg: true): Demo<true>
function func(arg: boolean): Demo<boolean> {
if (arg === true) {
const a = arg;
return { a: "hello" };
} else {
return { b: "world" };
}
};
const out = func(true);
How can I understand this better?
看看this GitHub thread (also see the original issue)。归结为 TypeScript 在使用条件类型时不支持缩小函数 return 类型。由于 Demo
类型的解析取决于泛型类型参数 T
,这与直接在 return 类型注释中编写条件相同。
如果我们重写 Demo
类型(仅用于演示目的),问题应该会变得更清楚:
type D<T extends boolean> = {
true: {
a: string
},
false: {
b: string
}
}[`${T}`];
const func = <T extends boolean>(arg: T): D<T> => {
if (arg) {
return {a: "hello" }; //Type '{ a: string; }' is not assignable to type '{ a: string; } & { b: string; }'
} else {
return { b: "world" }; //Type '{ b: string; }' is not assignable to type '{ a: string; } & { b: string; }'
}
};
现在应该 crystal 清楚 D<T>
仍未解决 直到 您为类型参数提供参数。这就是 const out = func(true);
被正确推断的原因。
How do I solve it?
您几乎只能使用 as Demo<T>
之类的类型断言,或者删除泛型类型参数并使用