避免 TypeScript 代码中使用模糊的 Object 或 {}
在 TypeScript 的世界里,当我们期望一个对象但不确定对象的具体结构时,通常会使用 Object
或 {}
作为类型。这就像收到一个神秘的包裹,你知道它在那里,但你不确定里面是什么。然而,有个小插曲:虽然这种做法乍一看很方便,但过多地依赖这些通用对象类型可能会导致一些意想不到的问题。让我们深入探讨一下,看看为什么在 TypeScript 代码中使用这些模糊类型可能是时候慎重考虑了。
理解使用 Object 或 {} 的问题
当我们有一个 TypeScript 变量存储任何对象,但对对象的结构不确定时,我们经常使用 Object
或 {}
这样的类型,如下所示:
type Param = Object;
// 或
type Param = {};
然后在各个地方使用它,比如函数参数:
代码语言:typescript复制function myFunc(obj: Param) {
console.log(obj);
}
但这会成为一个问题,因为我们知道在 JavaScript 中,Object
是一切的基础,因此允许像字符串、日期、布尔值等这样的值被传递而不会抛出 TypeScript 错误,如下所示:
myFunc({name: 'John', age: 30});
myFunc('abc');
myFunc(123);
myFunc(true);
myFunc([1,2,3]);
myFunc(new Date());
myFunc(() => {});
myFunc({});
既然我们已经看到了使用 Object
或 {}
引起的问题,现在是时候动手解决这些问题,探索一下解决这些问题的不同路径。通过寻找替代方案,我们可以为更加平稳、可预测的代码铺平道路。
解决方案1:使用 Record
我们可以在 TypeScript 中使用 Record
来解决这个问题。Record
接受两种类型,一个用于键,另一个用于值,如下所示:
type Param = Record<string, unknown>;
在这里,我们可以看到 <string, unknown>
被传递给 Record
,这意味着键的类型将是字符串,值的类型被标记为未知。
让我们看看在上面的示例 myFunc
中使用 Record
会发生什么:
type Param = { [key: string]: unknown };
function myFunc(params: Param) {
console.log(params);
}
myFunc({ name: 'John', age: 30 });
myFunc('abc');
myFunc(123);
myFunc(true);
myFunc([1, 2, 3]);
myFunc(new Date());
myFunc(() => {});
myFunc({});
在这里我们可以看到 TypeScript 开始抱怨像字符串、数字、布尔值等这样的值的类型。
解决方案2:使用索引
另一种方法是使用索引,可以为键和值分别定义类型。假设我们想要为键使用字符串类型,为值使用未知类型,那么我们可以定义我们的参数类型为:
代码语言:typescript复制type Param = {
[index: string]: unknown
}
注意:这里的 index
只是一个占位符,我们可以使用任何其他术语,比如 key
、property
、id
等,例如:
type Param = { [key: string]: unknown };
现在让我们看看如果在我们的示例代码中使用 index
会发生什么:
type Param = { [index: string]: unknown };
function myFunc(params: Param) {
console.log(params);
}
myFunc({ name: 'John', age: 30 });
myFunc('abc');
myFunc(123);
myFunc(true);
myFunc([1, 2, 3]);
myFunc(new Date());
myFunc(() => {});
myFunc({});
在上面的示例中,我们使用索引定义了类型 Param
,这就是当你传递像字符串、数字、布尔值等参数时,
我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!