javascript - 条件泛型类型
问题描述
我用不同的类型写了两次相同的代码,但它们是相同的。
第一次编译:
type X<B extends boolean> = { b1: B } & (B extends true ? { a1: 1 } : { a2: 2 })
function f<B extends boolean>(x: X<B>) {
console.log(x)
}
function f2(b: boolean) {
f(b ? { b1: true, a1: 1 } : { b1: false, a2: 2 })
}
f2(true)
以下有错误:
type X<B extends { b1: boolean }> = { b1: B['b1'] } & (B['b1'] extends true ? { a1: 1 } : { a2: 2 })
function f<B1 extends boolean>(x: X<{ b1: B1 }>) {
console.log(x)
}
function f2(b: { b1: boolean }) {
f(b.b1 ? { b1: true, a1: 1 } : { b1: false, a2: 2 })
^^^^^
ERROR ts(2345)
}
f2({ b1: true })
错误:
Argument of type '{ b1: true; a1: number; } | { b1: false; a2: 2; }' is not assignable to parameter of type 'X<{ b1: boolean; }>'.
Type '{ b1: true; a1: number; }' is not assignable to type 'X<{ b1: boolean; }>'.
Object literal may only specify known properties, and 'a1' does not exist in type 'X<{ b1: boolean; }>'.ts(2345)
问题
为什么第二个代码有错误?我怎样才能解决打字问题?
解决方案
在您的第一个示例中, B 扩展了布尔值。这允许 Typescript 更严格地推断类型,并允许 B 减少为之一true
或false
根据需要。考虑:
const test: X<boolean> = {b1: true, a2: 2}; // Compiles. Likely not what you want
const test2: X<true> = {b1: true, a2: 2}; // Does not compile, as expected
这意味着当您调用 f2 时,类型{ b1: true, a1: 1 }
实际上是X<true>
,并且{ b1: false, a2: 2}
是X<false>
。
在该示例中,如果将结果分配给变量,它将无法编译,因为您将无法严格定义类型。
function f2(b: boolean) {
const argument = b ? { b1: true, a1: 1 } : { b1: false, a2: 2 };
// type is { b1: boolean; a1: number; a2?: undefined } | { b1: boolean; a2: number; a1?: undefined; }
f(argument); // compile error
}
在您的第二个示例中,Typescript 只是没有足够的信息来评估编译类型的类型。
对您的第二个函数的此修改允许它编译
function f2(b: { b1: boolean }) {
if (b.b1) {
f({ b1: true, a1: 1 })
} else {
f({ b1: false, a2: 2 })
}
}
有关条件类型的更多信息,请查看https://www.typescriptlang.org/docs/handbook/advanced-types.html#conditional-types
推荐阅读
- python - 为什么访问 numpy 数组比使用 Cython 的 Pillow 图像慢 6 倍
- elasticsearch - 如何根据其他字段的值在摄取文档上添加新字段?
- c - 将二进制转换为十六进制数字系统的C程序
- python - 有没有一种更快的方法来使用 mibian 模块计算 csv/xl 文件中数百万行的隐含波动率?
- c# - 选择的库禁用 ASP.NET MVC 中 DropDownList 的验证
- gcc - C如何分配内存?
- c# - 当用户输入特定文本c#时,尝试显示文本文件中的特定文本行
- swift - iOS 13 Modals - 以编程方式调用滑动解除
- reactjs - Amplify+react:使用联合身份提供者托管 ui
- sql - 在特定日期每 2 周获取一次 SQL Server