微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在元组上使用映射类型时,为什么需要条件类型?

如何解决在元组上使用映射类型时,为什么需要条件类型?

这有效:

class Dog {
    speak() {
        return "woof" as const;
    }
}

type ExtractSpeak<T extends [...Dog[]]> = { [P in keyof T]: T[P] extends Dog ? ReturnType<T[P]["speak"]> : never };

// Type of Example is ["woof","woof"]
type Example = ExtractSpeak<[Dog,Dog]>;

但是,如果没有条件类型,为什么它不起作用?

// Error: Type '"speak"' cannot be used to index type 'T[P]'. (2536)
type ExtractSpeak<T extends [...Dog[]]> = { [P in keyof T]: ReturnType<T[P]["speak"]> };

除了具有T[P]方法的类型返回speak的类型之外,"woof"何时会引用?

解决方法

这是TypeScript中的错误;参见microsoft/TypeScript#27995。当您创建mapped type over a tuple/array时,出现的类型也将是元组/数组;也就是说,您实际上只是在映射数组的数字索引。但是在映射类型的定义中,编译器没有注意这一点。相反,它认为K in keyof T(其中T是数组类型)可能在每个可能的键上迭代K,如下所示:

type DogArrayKeys = keyof [Dog,Dog];
// number | "0" | "1" | "length" | "toString" | "toLocaleString" | "pop" | 
// "push" | "concat" | "join" | "reverse" | "shift" | "slice" | "sort" | 
// "splice" | "unshift" | "indexOf" | "lastIndexOf" | 
// ... 14 more ... | "includes"

例如,由于[Dog,Dog]["length"]的类型为2而不是Dog,因此编译器不允许您将T[K]视为Dog。 Blecch。

无论如何,这是一个错误,如果已修复,那就太好了。我想您可以转到ms / TS#27995,然后给它一个?。但实际上,它在任何优先级列表上可能都不高(目前在待办事项列表中)。标准的解决方法是只使用Extract<T[K],Dog>之类的条件类型并继续进行,这基本上就是上面的内容。

Playground link to code

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。