【问题标题】:Defining object shape variants in typescript在打字稿中定义对象形状变体
【发布时间】:2019-06-30 18:56:42
【问题描述】:

我正在尝试定义一个可以包含数据或错误的对象。

export type ActionResult = {
  data: any;
} | {
  error: any;
};

function test():ActionResult {
    return {
        data: 3
    }
}

当尝试访问我得到的函数结果时:

const v = test();
v.data = 23; // Property 'data' does not exist on type 'ActionResult'.  Property 'data' does not exist on type '{ error: any; }'

访问“数据”或“错误”的正确方法是什么?

【问题讨论】:

标签: typescript


【解决方案1】:

TypeScript 是如何理解你的代码的:

const v = test();
// v: {data: any} | {error: any}
v.data = 23;
// It is possible that 'v' is of type '{error: any}'
// In this case, an error might happen at runtime
// This error must be prevented right now - time to throw a TS error!

确保不会发生这种情况的一种方法是使用type guard 将联合类型限制为不会引发 TS 错误的类型:

const v = test();
// v: {data: any} | {error: any}
if ('data' in v) {
  // v: {data: any}
  v.data = 23;
  // no error!
}

你也可以通过在定义 v 时告诉 TypeScript 你确定 v 将有 data

const v = (test() as {data: any});
v.data = 23;

typescript playground上查看此代码

【讨论】:

  • 谢谢!有没有办法明确地说:“我知道结果只会有数据,不会有错误”?
  • @reflog 既然您将您的类型命名为ActionResult,我假设您将使用它来输入您的 API 响应。如果是这样,我强烈建议您过度考虑您的设计。您的端点不应返回两个不同的模型,具体取决于是否存在错误。
【解决方案2】:

这是带有区分联合的解决方案(我为每个联合成员添加了一个公共属性 dataType):

export type ActionResult = {
  dataType: "value",  
  data: any
} | {
  dataType: "error",  
  error: any
};

function test():ActionResult {
    return {
        dataType: "value",
        data: 3
    }
}

const v = test();
if ("value" === v.dataType){
   v.data = 23;
}

【讨论】:

    猜你喜欢
    • 2021-05-30
    • 1970-01-01
    • 2015-01-30
    • 2019-01-02
    • 2016-09-22
    • 2017-09-19
    • 2020-12-24
    • 2019-07-30
    • 1970-01-01
    相关资源
    最近更新 更多