当解析json格式的字符串时,我得到一个linter错误:
let mqttMessage = JSON.parse(message.toString())
// ESLint: Unsafe assignment of an `any` value. (@typescript-eslint/no-unsafe-assignment)
我控制message
的内容,所以我想告诉TS,从JSON.parse()
出来的实际上是一个对象。我该怎么做呢?
注意:我可以将警告静音,但我想知道是否有更好的方法来处理这个问题。
问题是JSON.parse
返回any
类型
这很公平——TypeScript不知道它是要解析成一个字符串、一个数字还是一个对象。
你有一个检查规则说'不允许将变量赋值为any'。
可以强制json。parse
的结果type SomeObjectIKnowAbout = {
};
const result = JSON.parse(message.toString()) as SomeObjectIKnowAbout;
我倾向于在这种情况下做的是创建一个特定的解析函数,它将在运行时断言对象确实是你所说的形状,并将进行类型转换,以便你可以在编写代码时将其视为该对象。
type SomeObjectIKnowAbout = {
userId: string;
}
type ToStringable = {
toString: () => string;
}
function parseMessage(message: ToStringable ) : SomeObjectIKnowAbout {
const obj = JSON.parse(message.toString()); //I'm not sure why you are parsing after toStringing tbh.
if (typeof obj === 'object' && obj.userId && typeof obj.userId === 'string') {
return obj as SomeObjectIKnowAbout;
}
else {
throw new Error ("message was not a valid SomeObjectIKnowAbout");
}
}
JSON.parse
不是泛型的,所以我们不能提供一个泛型参数来实现它。
你有几个选择。
简单的事情是,因为JSON.parse
返回any
,你可以只定义你要分配给它的类型:
let mqttMessage: MQTTMessage = JSON.parse(message.toString());
(我使用MQTTMessage
作为适当类型的替代)
function parseMQTTMessageJSON(json: string): MQTTMessage {
const x: object = JSON.parse(json);
if (x && /*...appropriate checks for properties here...*/"someProp" in x) {
return x as MQTTMessage;
}
throw new Error(`Incorrect JSON for 'MQTTMessage' type`);
}
那么你的代码是:
let mqttMessage = parseMQTTMessageJSON(message.toString());
作为类型断言和运行时包装函数的替代方法,您可以利用声明合并来用parse
方法的泛型重载来扩展全局JSON
对象。这将允许您传递期望的类型,并在解析时使用reviver
时提供改进的智能感知:
interface JSON {
parse<T = unknown>(text: string, reviver?: (this: any, key: keyof T & string, value: T[keyof T]) => unknown): T
}
type Test = { a: 1, b: "", c: false };
const { a, b, c } = JSON.parse<Test>(
"{"a":1,"b":"","c":false}",
//k is "a"|"b"|"c", v is false | "" | 1
(k,v) => v
);
或者,如果您依赖于声明文件来扩展全局接口:
declare global {
interface JSON {
parse<T = unknown>(text: string, reviver?: (this: any, key: keyof T & string,
value: T[keyof T]) => unknown): T
}
}
游乐场