TypeScript 中动态访问对象的属性

TypeScript 中动态访问对象的属性:

  1. 使用 keyof typeof obj 作为动态密钥的类型,例如 type ObjectKey = keyof typeof obj;
  2. 使用括号表示法访问对象的属性,例如 obj[myVar]
const obj = {
  name: 'Tom',
  country: 'Chile',
};

type ObjectKey = keyof typeof obj;

const myVar = 'name' as ObjectKey;

console.log(obj[myVar]); // 👉️ Tom

keyof typeof 语法允许我们获得对象键的联合类型。

const obj = {
  name: 'Tom',
  country: 'Chile',
};

// 👇️ type ObjectKey = "name" | "country"
type ObjectKey = keyof typeof obj;

const myVar = 'name' as ObjectKey;

通过这种方式,我们可以通知 TypeScript myVar 变量将只存储一个等于对象中的键之一的字符串。

现在我们可以动态访问对象属性了。

const obj = {
  name: 'Tom',
  country: 'Chile',
};

// 👇️ type ObjectKey = "name" | "country"
type ObjectKey = keyof typeof obj;

const myVar = 'name' as ObjectKey;

console.log(obj[myVar]); // 👉️ Tom

这是必需的,因为 TypeScript 并不总是能够根据需要确定字符串的类型。

const obj = {
  name: 'Tom',
  country: 'Chile',
};

// 👇️ const myVar: string
const myVar = 'na' + 'me';

// ⛔️ Error: No index signature with a parameter
// of type 'string' was found on type '{ name: string; country: string; }
console.log(obj[myVar]); // 👉️ Tom

myVar 的类型是一个字符串,并不是所有的字符串都是对象的属性,所以 TypeScript 提示我们不能安全地动态访问该属性。

如果我么尝试将 myVar 的类型设置为对象键的联合,仍然会收到错误。

const obj = {
  name: 'Tom',
  country: 'Chile',
};

// 👇️ type ObjectKey = "name" | "country"
type ObjectKey = keyof typeof obj;

// ⛔️ Error: Type 'string' is not assignable
// to type '"name" | "country"'.
const myVar: ObjectKey = 'na' + 'me';

解决这个问题的最简单方法是使用类型断言。

const obj = {
  name: 'Tom',
  country: 'Chile',
};

// 👇️ type ObjectKey = "name" | "country"
type ObjectKey = keyof typeof obj;

// 👇️ const myVar: "name" | "country"
const myVar = ('na' + 'me') as ObjectKey;

console.log(obj[myVar]); // 👉️ Tom

我们也可以直接在方括号中使用类型断言。

const obj = {
  name: 'Tom',
  country: 'Chile',
};

// 👇️ const myVar: string
const myVar = 'na' + 'me';

// 👇️ type ObjectKey = "name" | "country"
type ObjectKey = keyof typeof obj;

console.log(obj[myVar as ObjectKey]); // 👉️ Tom

但是,使用这种方法,每次尝试动态访问对象的属性时都必须使用类型断言。