本文介绍了打字稿打字的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
请看下面的打字稿片段。为什么不抛出编译错误呢?这难道不是一个明显的打字错误吗?我必须更改什么才能使它再次成为类型安全的?TYVM
type A<P> = {
p?: never,
q?: Partial<P>
}
type B<P> = {
p?: Partial<P>
q?: never
}
type C<P> = A<P> | B<P>
const c: C<{ a: number}> = {
p: {
a: 1,
b: 2 // <------ Why is this allowed?!?
}
}
console.log(c)
单击here观看演示
推荐答案
这是一个known bug,其中excess property checking不以人们期望的方式应用于涉及联合和交集的嵌套类型。额外的属性检查是类型系统的一种附加功能,它只适用于对象文字,所以当它不适用时,就会回到structural subtyping规则,其中类型{a: A, b: B}
是{a: A}
的子类型,因此前一种类型的值应该可以赋给后一种类型的变量。您可能想要转到the issue in Github并给它一个👍,或者解释您的用例(如果您认为它比那里列出的用例更引人注目)。希望有一天会有解决办法。
type Exactify<T, K extends keyof any>
= T & { [P in Exclude<K, keyof T>]?: never };
type A<P, K extends keyof any=never> = {
p?: never,
q?: Partial<Exactify<P, K>>
}
type B<P, K extends keyof any=never> = {
p?: Partial<Exactify<P, K>>
q?: never
}
type C<P, K extends keyof any = never> = A<P, K> | B<P, K>
type KeyofKeyof<T> =
keyof T | { [K in keyof T]: T[K] extends object ? keyof T[K] : never }[keyof T];
const asC = <T extends C<{ a: number }, KeyofKeyof<T>>>(c: T) => c;
const c = asC({
p: {
a: 1,
b: 2 // <------ error
}
})
是的,很难看。不确定这对你来说是否值得。它的工作方式是说C<P, K>
与您的C<P>
相同,只是增加了P
类型以显式排除K
中的所有额外属性。然后,我们使用帮助器函数asC()
来推断给定传入参数的K
的类型。因为有问题的键嵌套在下一层,所以我需要一个KeyofKeyof<T>
类型来从下一层提取键(您不可能在不触及循环类型的情况下为所有级别提取键)。
现在将显示所需的错误。是吗?我想是的。
不管怎样,希望这会有帮助。祝你好运!
这篇关于打字稿打字的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!