【问题标题】:In TypeScript, what do "extends keyof" and "in keyof" mean?在 TypeScript 中,“extends keyof”和“in keyof”是什么意思?
【发布时间】:2021-06-30 22:15:25
【问题描述】:

在 TypeScript 中,某些类型是使用 extends keyofin keyof 定义的。我试图理解它们的意思,但到目前为止我没有成功。

我得到的是,keyof 单独返回一个联合类型,该类型具有所有名称作为可能的值,这些名称作为属性名称存在于您在 keyof 之后指定的类型上。

type T = keyof string;

T 因此等价于startsWith | endsWith | trim | substring | ...

这对吗?

现在,如果我尝试思考 extends keyofin keyof 的含义,我的直觉会说:

  • extends keyof 是派生自 T 的任何类型,即它具有所有这些可能的值,但可能更多。
  • in keyof 是从 T 获取值的任何类型,但不一定是所有类型(有可能,但可能更少)。

因此,从这个 POV 来看,extends keyof 将描述 >= 关系,in keyof 将描述 <= 关系。这个对吗?如果不是,什么是正确的?

【问题讨论】:

    标签: typescript keyof


    【解决方案1】:

    对于任何类型的Tkeyof TT 的已知公共属性名称的联合。

    例子:

    interface Person {
      age: number;
      name: string;
    }
    
    type PersonKeys = keyof Person; // "age" | "name"
    

    因此,您对keyof string 产生startsWith | endsWith | trim | ... 的假设是正确的。你可以在lookup type release notes了解更多。

    扩展keyof

    extends,在这种情况下,用于constrain the type of a generic parameter。示例:

    <T, K extends keyof T>

    K 因此只能是T 的公共属性名称。它与扩展类型或继承无关,与extending interfaces 相反。

    extends keyof 的用法可能如下:

    function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
      return obj[key];
    }
    
    const person: Person = {
      age: 22,
      name: "Tobias",
    };
    
    // name is a property of person
    // --> no error
    const name = getProperty(person, "name");
    
    // gender is not a property of person
    // --> error
    const gender = getProperty(person, "gender");
    

    除了documentation on index types,我找到了this helpful article

    在关键

    in 用于定义一个index signature,我们想用字符串、数字或符号文字的联合来键入。结合keyof,我们可以使用它来创建一个所谓的映射类型,它重新映射原始类型的所有属性。

    in keyof 的用法可能如下:

    type Optional<T> = { 
      [K in keyof T]?: T[K] 
    };
    
    const person: Optional<Person> = {
      name: "Tobias"
      // notice how I do not have to specify an age, 
      // since age's type is now mapped from 'number' to 'number?' 
      // and therefore becomes optional
    };
    

    除了documentation on mapped types,我又找到了this helpful article

    趣事:我们刚刚构建的Optional&lt;T&gt; 类型与官方Partial&lt;T&gt; 实用程序类型具有相同的签名!

    【讨论】:

    • 感谢您的回答。我被困在extends keyof 的概念上。他们真的应该为这种情况选择不同的关键字。这确实是混乱和违反直觉的。来自docT extends LengthwiseK extends keyof T,其中extends 关键字的含义完全不同。
    • 这是否意味着,extends 始终用于泛型,in 始终用于索引评估器?
    • @JunleLi 是的,你不能反过来使用它们。抱歉回复晚了,我好像错过了你的评论!
    • @cbdeveloper A extends B 表示“一些AB 的子类型”。如果B 是keyof 类型,那么A 是集合中的一个字符串——并且由于索引访问类型,类型检查器可以详细说明使用这个字符串的代码。
    • 比其他非常棒的官方手册给出的解释要清楚得多。
    猜你喜欢
    • 2019-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-05
    • 1970-01-01
    • 1970-01-01
    • 2021-01-25
    相关资源
    最近更新 更多