首页 > 解决方案 > 如何解压作为 Typescript 联合且可能是数组的返回类型?

问题描述

我有一个返回类型如下所示的函数:

type FuncReturns = TypeA | [any, TypeB];

在哪里...

interface TypeA {
    name: string;
    count: number;
}

interface TypeB {
    color: string;
    volume: number;
    edges: number;
}

const myAwesomeFunc = (val : string | number, obj : object = {}) : FuncReturns=>{
    switch(typeof val){
       case "string" : {
           return {
               name: val,
               count: 1
           }
       } case "number" : {
           return [obj, {
               color: "blue",
               volume: 6,
               edges: 6
           }]
       } default {// should never be used in this way
            throw new Error("This is nonsense.")
       }
    }
} 

...应该像这样可以解包(可破坏)...

const {name, count} = myAwesomeFunc(someValue);

......像这样......

const [object, {color, volume, edges}] = myAwesomeFunc(someOtherValue);

基于一些内部逻辑,该函数可能返回一个我想解包的对象 TypeA 或一个我也想解包的数组 TypeB。不幸的是,我没有接受数组解包运算符作为可以应用于返回类型的可能方法之一,而是最终得到一个错误,指出 union type is not an array type。我可以为我的用例想出几种解决方法,但我想知道是否有一种既定的方法来解决这个问题。

注意: 正如 alekxsor 适当指出的那样,我实际上只希望函数向下移动两个分支:(1)字符串 val 以返回对象和(2)数字 val 以返回数组。最佳解决方案将启用类型检查,以便在提供字符串时,预期的返回类型将是对象等等。

标签: typescripttypescript-typings

解决方案


type FuncReturns = TypeA | [any, TypeB]

const myAwesomeFunc = (val : string | number, obj : object = {}): FuncReturns {...}

这个签名有效地表明在具体类型中它可以执行以下任何操作:

  (val: string, obj: ...) => TypeA
  (val: string, obj: ...) => [any, TypeB]
  (val: number, obj: ...) => TypeA
  (val: number, obj: ...) => [any, TypeB]

这无疑不是它在实践中所做的事情。传达确切含义的最简洁方法是使用函数重载

function myAwesomeFunc(val: string): TypeA
function myAwesomeFunc(val: number, obj: object): [any, TypeB]
function myAwesomeFunc(val: string | number, obj?: object): TypeA | [any, TypeB] {
  // actual implementation
}

版本更新const

要使其与const语法一起使用,您可以将其定义为可调用接口或函数类型的交集:

interface MyAwesomeFunc {
  (val: string): TypeA
  (val: number, obj: object): [any, TypeB]
}

or

type MyAwesomeFunc 
  = (((val: string) => TypeA) 
  & ((val: number, obj: object) => [any, TypeB]))

const myAwesomeFunc: MyAwesomeFunc = (val: string | number, obj?: object): any {
 // ...
}

TS游乐场


推荐阅读