【问题标题】:Typescript type declaration with square brackets带方括号的打字稿类型声明
【发布时间】:2021-01-12 06:27:58
【问题描述】:

刚刚在https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-differentiating-types找到以下代码sn-p

type FunctionPropertyNames<T> = {
  [K in keyof T]: T[K] extends Function ? K : never;
}[keyof T];
type FunctionProperties<T> = Pick<T, FunctionPropertyNames<T>>;

类型声明后的[keyof T]是什么意思以及它是如何命名的?

另外,[keyof T] 看起来像是在提示编译器,FunctionalPropertyNames 中的键是来自 T 的键,但为什么编译器不能从 [K in keyof T] 推断这一点?

【问题讨论】:

    标签: typescript typescript-typings


    【解决方案1】:

    简单解释:这种用法,获取所有属性的所有值类型。


    首先,[] 通过使用一个键(或多个键)访问该类型来钻取该类型之后

    type A = { foo: string }
    type B = A['foo'] // string
    

    其次,这里有一个映射类型。这意味着它是一种映射某种类型的所有键的类型,对其进行转换,然后返回一个新类型。

    所以让我们先看看这部分:

    type StripNonMethods<T> = {
      [K in keyof T]: T[K] extends Function ? K : never;
    }
    

    无论T 是什么,这将为T 的所有键创建一个类型,其中每个属性的值是属性名称(如果值是函数)或never(如果它是不是函数)。

    这会改变这个:

    type T1 = { a(): void, b: number }
    

    进入:

    type T2 = StripNonMethods<T1> // { a: 'a', b: never }
    

    但这里想要的结果是字符串'a',因为我们试图获取所有作为函数的属性名称。所以我们用它自己的键深入到这个类型,它返回所有属性的所有值作为一个联合,最后有[keyof T]

    现在会返回:

     type T3 = T2[keyof T2] // 'a' | never
    

    而且因为never 永远不会存在,根据定义,它被简化为联合之外,你会得到:

    'a'
    

    Playground

    【讨论】:

      【解决方案2】:

      带方括号的语法称为Indexed access types。它用于获取特定类型的属性类型。例如:

      假设我们有一个名为AlmostRectangle 的类型:

      type AlmostRectangle = {
        name: string;
        a: number;
        b: number;
        start: Date;
      };
      

      我们可以通过使用索引访问类型语法来获取特定属性的类型:

      type NameType = AlmostRectangle["name"]; // string
      

      我们可以将键名的并集传递给方括号,以获得属性类型的并集,例如:

      type MultipleTypes = AlmostRectangle["name" | "start"] // string | Date
      

      keyof AlmostRectangle 返回 AlmostRectangle 属性名称的联合:"name" | "a" | "b" | "start"。我们可以用它来获得所有的AlmostRectangle 属性类型:

      type AlmostRectangleProperty = AlmostRectangle[keyof AlmostRectangle] // string | number | Date
      

      【讨论】:

        猜你喜欢
        • 2019-02-16
        • 1970-01-01
        • 2017-08-12
        • 2021-01-20
        • 2022-01-06
        • 2017-12-05
        • 2018-06-12
        • 2017-06-10
        • 1970-01-01
        相关资源
        最近更新 更多