【问题标题】:How can I define a type for a set of inputs that map to a set of outputs for a function in TypeScript?如何为一组输入定义类型,这些输入映射到 TypeScript 中函数的一组输出?
【发布时间】:2019-07-12 06:35:25
【问题描述】:

我想做如下的事情:

enum Opts {
    One = 'one',
    Two = 'two',
    Three = 'three',
}

interface OneOpts {
    foo: string;
    bar: string;
}

interface TwoOpts {
    one: string;
    two: string;
}

interface ThreeOpts {
    a: string;
    b: string;
}

interface FunctionResponse<T> {
    id: string;
    href: string;
    options: T;
}

type StartArgs =
    | [Opts.One, OneOpts]
    | [Opts.Two, TwoOpts]
    | [Opts.Three, ThreeOpts]

type FunctionReturn = FunctionResponse<OneOpts | TwoOpts | ThreeOpts>

const start = async (...args: StartArgs): Promise<FunctionReturn> => {
    const [ first, second ] = args
    //...
    const results: FunctionReturn = await new Promise(() => {
        //...
    })

    return results
}

// Current:
start(Opts.One, { foo: 'string', bar: 'another' })
.then((result: TwoOpts) => { // passed :(
    //...
})

// Desired result:
start(Opts.One, { foo: 'string', bar: 'another' })
.then((result: TwoOpts) => { // ERROR
    //...
})

具体来说,我想根据发送给它的一组输入参数来推断函数的返回类型。在 TypeScript 中执行此操作的好方法是什么?

我能够通过StartArgs 类型正确关联输入参数。但是,如果我尝试通过以下方式为整体功能执行此操作:

type myFunc = 
    | (args: [type, type2]): type3
    | (args: [type, type2]): type3
    | (args: [type, type2]): type3

在这种情况下,编译器会抱怨 ...args 会自动转换为 any[]

Playground Example

【问题讨论】:

    标签: typescript


    【解决方案1】:

    您可以为此使用函数重载:

    interface OneOpts {
      foo: string;
      bar: string;
    }
    
    interface TwoOpts {
      one: string;
      two: string;
    }
    
    interface ThreeOpts {
      a: string;
      b: string;
    }
    
    interface FunctionResponse<T> {
      id: string;
      href: string;
      options: T;
    }
    
    function start(opts: OneOpts): Promise<FunctionResponse<OneOpts>>;
    function start(opts: TwoOpts): Promise<FunctionResponse<TwoOpts>>;
    function start(opts: ThreeOpts): Promise<FunctionResponse<ThreeOpts>>;
    function start(opts: OneOpts | TwoOpts | ThreeOpts) {
      return Promise.resolve({
        id: "xyz",
        href: "url",
        options: opts
      });
    }
    
    start({ foo: "foostring", bar: "barstring" }).then(
      (result: FunctionResponse<OneOpts>) => console.log(result)
    );
    

    Playground Link

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-02
      • 2021-04-05
      • 2016-07-18
      • 1970-01-01
      • 2021-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多