keyof typeof 泛型约束如何工作?

Cha*_*ark 1 typescript

TypeScript 中的“keyof typeof”是什么意思?

我发现了上面的问题,作者问了我想问的完全相同的问题,但没有答案找到问题的重点。

假设有这个通用方法和一个类。

function fn<K extends keyof typeof A>(key: K) ...

class A {
    static a;
    static b;
}
Run Code Online (Sandbox Code Playgroud)

我的理由是:

  1. typeof 关键字返回一个字符串,显示 js 基本类型之一。

  2. 所以无论值是什么,返回类型都是字符串。

  3. 所以 keyof "..." 应该是索引和“长度”以及字符串文字可以拥有的东西。在这种情况下,keyof "function" 应该返回类型 "0" | "1" | "2" | "3" | "4" | “5” | "6" | "7" | “长度”。

  4. 但实际行为是 typeof 类 A 返回构造函数。

这怎么会发生?

Cer*_*nce 5

typeof 关键字返回一个字符串,显示 js 基本类型之一。

这对于 JavaScript 来说是正确的,但在 Typescript 中typeof,根据上下文可能意味着多种含义。与在 JS 中不同,在 TS 中,whentypeof处于预期类型的上下文中,typeof expression将评估为(TypeScript 确定的)expression. 例如:

let num = 5;
type Num = typeof num;
Run Code Online (Sandbox Code Playgroud)

导致Num类型为number. 这不是字符串 'number'- 它是 TypeScript Type number

所以,在你的代码中:

function fn<K extends keyof typeof A>(key: K) ...
Run Code Online (Sandbox Code Playgroud)

由于K extends keyof ...是一个类型上下文(它对于配置 TypeScript 对代码的解释很有用,但在发出的 JavaScript 中不存在),以下typeof指示 TypeScript 替换typeof A为 A 是 TypeScript 检测到的类型。

相反,当不在类型上下文中时:

let someStr = 'foo';
const theType = typeof someStr;
Run Code Online (Sandbox Code Playgroud)

在这里,typeof运行时 JavaScript 中使用,在发出的代码中,而不是作为 TypeScript 特定的语法,因此它会在运行时theType分配值'string'

typeof可以使用的两种方式是完全不同的。