我已经定义了这个类型:
type StoreDataValue = string | Record<PropertyKey, any>;
我有一个这种类型的参数value
首先,我创建了一个临时变量并将其分配给value
。
然后我做一个检查,看看它是否不同于string
使用JSON.stringify
将其转换为string
。
但是typescript并没有推断出最终的结果是string
。
当我尝试使用最后的parsedValue
:
类型为'StoreDataValue'的实参不能赋值给'string'类型的形参。类型'Record<PropertyKey,>'不能赋值给类型'string'.ts(2345)
代码如下:
type StoreDataValue = string | Record<PropertyKey, any>;
const storeData = async (key: string, value: StoreDataValue) => {
try {
let parsedValue = value;
if (typeof parsedValue !== "string") {
parsedValue = JSON.stringify(value);
} else {
parsedValue = value;
}
await AsyncStorage.setItem(key, parsedValue);
} catch (e) {
// ...
}
};
如果我只是将typeof parsedValue ...
行更改为typeof value ...
,那么推理工作。
是我做错了什么还是没有看到明显的?
问题是:
if (typeof parsedValue !== "string") {
parsedValue = JSON.stringify(value);
}
只将parsedValue
的类型缩小为string
,但不会自动缩小value
的类型。所以,在这行之后,TypeScript类型检查器仍然认为value
是string | Record<PropertyKey, any>
类型,当你在else
子句中将value
赋值给parsedValue
时,TypeScript检查器认为你可能会将parsedValue
的类型还原为string | Record<PropertyKey, any>
。
如果您删除If语句的else
子句,您将看到错误消失。这样做的原因是,在parsedValue
被缩小到string
之后,将不再有一个将string | Record<PropertyKey, any>
类型的值(即value
参数的类型)分配给parsedValue
的代码路径:
let parsedValue = value;
if (typeof parsedValue !== "string") {
parsedValue = JSON.stringify(value);
}
await AsyncStorage.setItem(key, parsedValue); // This works just fine