Typescript - 嵌套映射类型给出令人困惑的类型提示

标签 typescript typescript-generics

我写了一个嵌套的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 }

我看不出您的 T6T7 类型之间存在差异。因此,看起来这完全是由编译器错误引起的,并且当 TypeScript 3.5 在 2019 年 5 月 30 日或前后发布时应该会消失。

好的,祝你好运!

关于Typescript - 嵌套映射类型给出令人困惑的类型提示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56050214/

相关文章:

javascript - 属性 'shouldComponentUpdate' 不可分配给同一属性

Angular 11 : Unit testing an HttpInterceptor - can't get catchError to work in test

typescript - 如何使一个对象属性依赖于泛型类型中的另一个对象属性?

typescript - 如何使用嵌套接口(interface)限定 TypeScript 泛型类型的范围

javascript - 是否可以从 typescript 接口(interface)创建一个等效的 joi ?

javascript - Building Typescript : [! ] Error: Unexpected token (注意你需要插件来导入不是 JavaScript 的文件)

typescript - 在 Nestjs 中用 Jest 手动模拟不起作用

javascript - 如何在 typescript 中以通用方式扩展第 3 方类?

typescript - 将通用 typescript 类型限制为单个字符串文字值,不允许联合

TypeScript:为什么我不能分配类型为 { a: "a", b: "b"} 的对象的有效字段