如何缩小对象属性值'unknown'?



我有一个类型为Record<string, unknown>的对象,我正在使用.reduce()迭代所有属性。

现在,我想对作为字符串的每个属性值执行一个操作。

但我不知道如何将属性值从unknown缩小到string

我的代码看起来像这样:

const obj: Record<string, unknown> = {
foo: 'bar',
}
Object.keys(obj).reduce((result, key) => {
if (typeof obj[key] === 'string') {
const stringValue = obj[key]; // 'stringValue' should be 'string' type, but is currently 'unknown'
// Do something here with a string
}
return {
...result,
};
}, {});

这是TypeScript游乐场链接。

您可以首先将属性处的值分配给局部变量,然后缩小该变量的范围:

const obj: Record<string, unknown> = {foo: 'bar'};
const onlyStrings: Record<string, string> = {};
for (const key in obj) {
const value = obj[key];
//^? const value: unknown
onlyStrings[key] = value; /*
~~~~~~~~~~~~~~~~
Type 'unknown' is not assignable to type 'string'.(2322) */
if (typeof value === 'string') {
onlyStrings[key] = value; // ok
//^? const value: string
}
}

或者,您可以使用一个返回类型谓词的函数(这样的函数被称为类型保护(来直接缩小对象类型:

const obj: Record<string, unknown> = {foo: 'bar'};
const onlyStrings: Record<string, string> = {};
function objHasStringValueAtKey <K extends string, T extends Record<K, unknown>>(
obj: T,
key: K,
): obj is T & Record<K, string> {
return typeof obj[key] === 'string';
}
for (const key in obj) {
if (objHasStringValueAtKey(obj, key)) {
onlyStrings[key] = obj[key]; // ok
}
}

TS游乐场

在您的示例中,缩小表达式很简单,所以我可能会使用前一种方法,但对于更复杂的数据类型和结构,类型谓词可以非常巧妙地封装需要执行的运行时验证,以维护类型安全并帮助降低主应用程序逻辑代码中的语法复杂性,从而更容易推理。

将值存储在变量中,而不是在对象上访问它。变量的类型可以缩小,但不能缩小对象的属性(源(

Object.keys(obj).reduce((result, key) => {
const val = obj[key];
if (typeof val === 'string') {
// Do something here with val as a string
}
return {
...result,
};
}, {});

相关内容

最新更新