在 TypeScript 中,“extends keyof”和“in keyof”是什么意思?

Gol*_*den 63 typescript keyof

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

我得到的是,keyof单独返回一个联合类型,该类型将所有名称作为可能的值存在于您在keyof.

type T = keyof string;
Run Code Online (Sandbox Code Playgroud)

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

这样对吗?

现在,如果我去想想什么extends keyofin keyof意味着,我的直觉以下称:

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

所以,从这个 POVextends keyof将描述一个>=关系,in keyof将描述一个<=关系。这样对吗?如果不是,那什么是正确的?

Tob*_*ler 127

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

例子:

interface Person {
  age: number;
  name: string;
}

type PersonKeys = keyof Person; // "age" | "name"
Run Code Online (Sandbox Code Playgroud)

因此,您的keyof string收益率假设startsWith | endsWith | trim | ...是正确的。您可以在查找类型发行说明中了解更多信息。

扩展keyof

extends,在这种情况下,用于约束泛型参数的类型。例子:

<T, K extends keyof T>

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

的用法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");
Run Code Online (Sandbox Code Playgroud)

除了有关索引类型文档之外,我还发现了这篇有用的文章

在keyof中

in当我们定义一个索引签名时使用,我们希望用字符串、数字或符号文字的联合输入。结合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
};
Run Code Online (Sandbox Code Playgroud)

除了有关映射类型文档之外,我再次找到了这篇有用的文章

有趣的事实Optional<T>我们刚刚构建的类型与官方Partial<T>实用程序类型具有相同的签名!

  • 感谢你的回答。我一直坚持“扩展 keyof”的概念。他们确实应该针对这种情况选择不同的关键字。这实在是令人困惑和违反直觉。来自[doc](https://www.typescriptlang.org/docs/handbook/generics.html#generic-constraints):“T extends Lengthwise”和“K extends keyof T”,其中“extends”关键字完全意味着某些东西不同的。 (12认同)
  • 比其他非常棒的官方手册给出的解释要清楚得多。 (3认同)
  • 这是否意味着“extends”始终用于通用,“in”始终用于索引评估器? (2认同)
  • @JunleLi 是的,你不能以相反的方式使用它们。抱歉这么晚回复,我好像错过了你的评论! (2认同)