我写了一个嵌套的Omit
以两种不同的方式输入,但对我来说更有意义的一种给出了复杂的类型提示,而不太直观的一种实际上看起来最好。这里是:
type HasSameNested = {
a: {
c: number; d: string
},
b: {
c: string; d: number
}
}; // flipped C and D types
type Omit2<T, K1 extends keyof T, K2 extends keyof T[K1]> = {
[P1 in keyof T]: P1 extends K1 ? {
[P2 in Exclude<keyof T[K1], K2>]: T[P1][P2]
} : T[P1]
}
type Omit2_2<T, K1 extends keyof T, K2 extends keyof T[K1]> = {
[P1 in keyof T]: P1 extends K1 ? {
[P2 in Exclude<keyof T[P1], K2>]: T[P1][P2]
} : T[P1]
}
type omit_union = Omit2<HasSameNested, 'a' | 'b', 'c'>;
let T6: omit_union;
T6.a; // works, type is { d: string }
T6.b; // works, type is { d: number }
type omit_union_2 = Omit2_2<HasSameNested, 'a' | 'b', 'c'>;
let T7: omit_union_2;
T7.a.d = 'a'; // works but types are ugly:
// a: { [P2 in Exclude<keyof HasSameNested[K1 & "a"], "c">]: HasSameNested[K1 & "a"][P2]; }
// d: d: HasSameNested[K1 & "a"]["d"]
T7.b.d = 4; // works but types are ugly, as above
为T7.b.d
分配了错误的类型或T7.a.d
确实告诉我例如string is not assignable to number
,但是我不明白为什么使用 Exclude<keyof T[P1], K2>
尽管 P1 in keyof T
却给出了如此复杂的打字和P1 extends K1
,和Exclude<keyof T[K1], K2>
给出正确的类型。
最佳答案
对我来说,这看起来像是编译器中的一个错误。我刚刚提交了Microsoft/TypeScript#31326并将从那里报告更新的信息。祝你好运!
更新,2019-05-10:这已被一位语言设计者标记为错误。不确定何时会修复它,但至少我们知道您对该类型信息感到困惑是正确的。
更新,2019-05-11:正如您所注意到的,这个错误现在是 fixed并已合并到master
中。这意味着如果您现在使用 typescript@next
尝试代码,您应该会看到新的行为:
type omit_union_2 = Omit2_2<HasSameNested, 'a' | 'b', 'c'>;
declare let T7: omit_union_2;
T7.a; // works, type is { d: string }
T7.b; // works, type is { d: number }
我看不出您的 T6
和 T7
类型之间存在差异。因此,看起来这完全是由编译器错误引起的,并且当 TypeScript 3.5 在 2019 年 5 月 30 日或前后发布时应该会消失。
好的,祝你好运!
关于Typescript - 嵌套映射类型给出令人困惑的类型提示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56050214/