TypeScript:如何将接口(interface)映射到自定义数据类型

标签 typescript

我有以下类型:

interface USER {
    email: string;
    age: number;
}
interface SCORES {
    likes: number;
    followers: number;
}

然后复合状态如下图:

interface UserStats {
    user: USER;
    stats: SCORES;
}

现在我得到一个 payload看起来像这样:

{type: 'user', values: {email:"<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bfdedddcffd8d2ded6d391dcd0d2" rel="noreferrer noopener nofollow">[email protected]</a>",age: 21}} 或者 {type: 'stats', values: {likes:20,followers: 21}}

在解构上述有效负载时,我需要分配其类型,使其涵盖这两种情况,例如:

type payloadKeyTypes = 'user' | 'stats'
type configPayload = USER | SCORES
interface payloadType {
    [payloadKeyTypes]: configPayLoad
}

但这说:A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type

我该如何解决这个问题?

最佳答案

禁止在接口(interface)中使用联合类型作为索引签名。然而,自从 typescript 4.4您可以使用符号和模板文字字符串。

在这种特殊情况下,值得使用 type Record因为它允许您使用联合:

interface USER {
    email: string;
    age: number;
}

interface SCORES {
    likes: number;
    followers: number;
}

interface UserStats {
    user: USER;
    stats: SCORES;
}

type payloadKeyTypes = 'user' | 'stats'

type configPayload = USER | SCORES

type payloadType = Record<payloadKeyTypes, configPayload> 

Playground

此外,请注意 typescript 中有命名约定。所有类型/接口(interface)/枚举都应大写并采用驼峰式命名。然而,这只是一个约定。

关于TypeScript:如何将接口(interface)映射到自定义数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70564498/

相关文章:

typescript - 重新添加从具有 `Omit` 的泛型类型中删除的属性会导致类型不兼容

typescript - NPM 条件脚本(Windows/Mac)应执行不同的命令)

typescript - Angular2 和 TypeScript : error TS2322: Type 'Response' is not assignable to type 'UserStatus'

typescript - TS2683 (TS) 'this' 隐式具有类型 'any' 因为它没有类型注释

javascript - 从指令添加指令

javascript - 运行 ngserve 与 ng build 时,index.html 中的差异加载脚本引用不同

javascript - 在 NativeScript 应用程序中与 TextField 交互时停止键盘覆盖

arrays - React useState 这里似乎不接受默认值?

typescript - 如何计算 TypeScript 对象类型中正在使用哪些属性?

typescript - react typescript : eslint max-length autofix does not work