首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何快速检查类型记录中的条件对象类型是否存在对象属性?

如何快速检查类型记录中的条件对象类型是否存在对象属性?
EN

Stack Overflow用户
提问于 2022-12-02 03:07:23
回答 2查看 38关注 0票数 0

下面有一个示例,它是我实际代码的一个非常简化的版本。

我有一个类型,可以是一个接口,也可以是另一个类似的类型:

代码语言:javascript
运行
复制
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

这是一个打字稿操场

现在,在我的代码中,当我试图简单地检查"emoji“是否在configs中定义时,它使它变得非常复杂,当然还有更简单的方法吗?

代码语言:javascript
运行
复制
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")
    }
})

但是打字本给我带来了一个错误

代码语言:javascript
运行
复制
Property 'emoji' does not exist on type '{ text?: string | undefined; }'.

所以我的问题是,我怎么才能让if("emoji" in chat.configs && chat.configs.emoji)不长得可笑呢?

EN

回答 2

Stack Overflow用户

发布于 2022-12-02 03:09:46

类型谓词可能有助于简化事情:https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates

代码语言:javascript
运行
复制
function hasDefinedEmoji(chat: Chat): chat is ChatEmoji & {configs: {emoji: string}} {
    return chat.type === "emoji" && Boolean(chat.configs.emoji);
}
代码语言:javascript
运行
复制
if(hasDefinedEmoji(chat)){
    console.log("Has an emoji", chat.configs.emoji) // works
}

缺点是你可以在谓词函数中犯一个错误,然后朝自己的脚开枪。你可以这样做,打字稿一点也不好看:

代码语言:javascript
运行
复制
function hasDefinedEmoji(chat: Chat): chat is ChatEmoji & {configs: {emoji: string}} {
    return true;
}
票数 1
EN

Stack Overflow用户

发布于 2022-12-03 22:46:10

只需为助手文件中的每个类型(如果需要)定义一个类型谓词:

代码语言:javascript
运行
复制
const isChatEmoji = (chat: ChatBase): chat is ChatEmoji => chat.type === "emoji";
const isChatMessage = (chat: ChatBase): chat is ChatMessage => chat.type === "message";

然后你可以:

代码语言:javascript
运行
复制
chats.filter(isChatEmoji).forEach(chat => console.log(chat.configs.emoji));
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74650451

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档