在 TypeScript 中,为什么使用“extends keyof”来声明带有约束的泛型类型参数,而不是使用“in keyof”?

问题描述 投票:0回答:1

typescriptlang.org 在其关于泛型的文章中解释了在声明类型参数时关键字“extends”的两种用法。

  1. 通用约束中。
interface Lengthwise {
  length: number;
}
 
function loggingIdentity<Type extends Lengthwise>(arg: Type): Type {
  console.log(arg.length);
  return arg;
}
  1. 声明受另一个类型参数约束的类型参数时
function getProperty<Type, Key extends keyof Type>(obj: Type, key: Key) {
  return obj[key];
}
 
let x = { a: 1, b: 2, c: 3, d: 4 };
 
getProperty(x, "a");

getProperty(x, "m");
// Error: Argument of type '"m"' is not assignable to parameter of type '"a" | "b" | "c" | "d"'.

在约束泛型类型时使用“extends”关键字是有意义的,这样它应该具有扩展类型的属性和方法。 (参见上面的第一次使用)。这也与 OOP 中继承中“extends”关键字的使用相匹配。

但是为什么上面第二个实例中使用“extends”关键字来约束泛型类型参数“Key”,所以它应该是类型参数“Type”的属性?为什么不使用关键字“in”作为“in keyof Type”,这样更有意义?

提前感谢您的回答和评论!

注: 我知道在声明索引签名时使用“in keyof”,如下所示。

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

我的问题是,当约束泛型类型参数时,为什么不使用相同的参数,而它应该是另一个类型参数的属性?

typescript generics keyof
1个回答
0
投票

类型

"a"
是类型
"a" | "b" | "c" | "d"
的子类型。

使用关键字

extends
进行类继承的语言会这样做 因为 继承类是被继承类的子类型。

keyof
是一个将一种类型转换为另一种类型的运算符,在该位置很容易成为
Key extends TypeKeys

© www.soinside.com 2019 - 2024. All rights reserved.