我有一个接口IMsg
,并且想解析JSON,所以我有一个实现我的IMsg
接口的对象。
此代码
interface IMsg {
text: string;
channels: Set<string>;
}
const msg: IMsg = JSON.parse(`{
"text": "test",
"channels": ["latest", "something"]
}`);
console.log(msg.channels.has('latest'));
将在运行时产生此错误:
TypeError: msg.channels.has is not a function
因为msg.channels
不是Set<string>
。
any
的对象分配给msg
类型的IMsg
?msg
的最惯用,简洁的方法是什么?答案 0 :(得分:1)
为什么编译器不会抱怨我试图将任何对象分配给IMsg类型的味精?
因为the type any
的确切含义是:请勿对此变量进行任何类型验证。就像JavaScript中一样,它可以是任何东西。
在没有太多样板代码的情况下将JSON正确解析为msg的最惯用,简洁的方法是什么?
我会用类似的东西
interface JsonMessage {
text: string;
channels: Array<string>;
}
const jsonMessage: JsonMessage = JSON.parse(`{
"text": "test",
"channels": ["latest", "something"]
}`);
const message: IMsg = {
text: jsonMessage.text,
channels: new Set(jsonMessage.channels)
};
答案 1 :(得分:0)
类似于JB Nizet的响应,我为JSON消息创建了一个单独的接口。但是,我不想重复每个字段。
以下代码将IMsg
作为基本接口。它将删除channels: Set<string>
字段,并将其添加回类型为string[]
的字段。为了在两者之间进行转换,我编写了一个转换器函数parseMsg
。
interface IMsg {
text: string;
channels: Set<string>;
}
// create new interface for JSON handling based on IMsg
// and replace "channels: Set<string>" with "channels: string[]"
type IMsgJSON = Omit<IMsg, 'channels'> & {
channels: string[],
};
// convert from IMsgJSON to IMsg
function parseMsg(msgJSON: IMsgJSON): IMsg {
const { channels, ...otherFields } = msgJSON;
return {
channels: new Set<string>(channels),
...otherFields,
};
}
let msg = parseMsg(JSON.parse(`{
"text": "test",
"channels": ["latest", "something"]
}`));
console.log(msg.channel.has('latest'));