下面的例子是我的实际代码的一个非常简化的版本。
我有一个类型,可以是接口,也可以是其他类型,如下所示:
interface ChatBase {
roomId?: string
type: "message" | "emoji"
configs: unknown
}
interface ChatMessage extends ChatBase {
type: "message",
configs:{
text?: string
}
}
interface ChatEmoji extends ChatBase {
type: "emoji",
configs: {
emoji?: string
}
}
type Chat = ChatMessage | ChatEmoji
这是一个 typescript 游戏场
现在在我的代码中,当我试图简单地检查“emoji”是否在configs
中定义时,它使它变得超级复杂,肯定有一个更简单的方法吗?
const chats: Chat[] = [
{ type: "message", configs: { text: "string" } },
{ type: "emoji", configs: { emoji: "string" } }
]
chats.map(chat=>{
if(chat.configs.emoji){ // <=== THROWS ERROR SHOWN BELOW
console.log("Has an emoji")
}
if("emoji" in chat.configs && chat.configs.emoji){ // <= Works but ridiculously long
console.log("Has an emoji")
}
if(chat.type === "emoji" && chat.configs.emoji){ // <= Works but sometimes I test for shared properties
console.log("Has en emoji")
}
})
但是 typescript 给我带来了一个错误
Property 'emoji' does not exist on type '{ text?: string | undefined; }'.
所以我的问题是,我怎样才能让if("emoji" in chat.configs && chat.configs.emoji)
不那么长呢?
2条答案
按热度按时间wqsoz72f1#
类型 predicate 可能有助于简化事情:https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates
第一个
缺点是你可能会在 predicate 函数中犯错误,从而搬起石头砸自己的脚。你可以这样做,而typescript不会眨一下眼睛:
j2qf4p5b2#
只需在帮助器文件中为每个类型定义一个类型 predicate (如果需要):
然后,您可以执行以下操作: