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

时间:2019-08-03 10:46:58

标签: typescript keyof

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

我得到的是,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将描述一个<=关系。它是否正确?如果没有,那是正确的吗?

1 个答案:

答案 0 :(得分:4)

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

您关于keyof string产生startsWith | endsWith | trim | ...的假设是正确的。

您对extends keyof的假设是不正确的。在这种情况下,extends用于定义generic parameter的类型,例如<T, K extends keyof T>。与extending interfaces相反,它与扩展类型或继承无关。

extends keyof的用法如下:

interface IAnimal {
  extinct: boolean;
  race: string;
}

function getKeyValue<T, K extends keyof T>(obj: T, key: K) {
  return obj[key];
}

const animal: IAnimal = {
  extinct: false,
  race: "dog"
};

const animalRace = getKeyValue(animal, "race"); // race is a key of IAnimal -> works
const animalAge = getKeyValue(animal, "age"); // age is not a key of IAnimal -> fails

除了documentation之外,我发现this文章很有帮助。

您对in keyof的假设也是不正确的。 in没有描述<=关系,它在定义要使用特定键键入的索引器属性时使用。

例如,我们可以使用它来创建一个新类型,该新类型将现有类型的所有属性重新映射为可选:

type Optional<T> = { [K in keyof T]?: T[K] };

const animal: Optional<IAnimal> = {
  extinct: true
};

除了documentation之外,我再次发现this文章很有帮助。