【问题标题】:How can infer return type of a function using the parameters supplied?如何使用提供的参数推断函数的返回类型?
【发布时间】:2020-09-09 18:04:59
【问题描述】:

我有一个泛型函数,它的返回类型基于输入类型。如何根据提供的参数正确确保返回类型的类型安全?

示例




interface IKeyboardService{
    type() : void;
}

class KeyboardService{
    type(){
        
    }
}

interface IMouseService{
    move() : void;
}

class MouseService{
    move(){

    }
}

interface ServiceTypeMapping{
    Keyboard: IKeyboardService,
    Mouse: IMouseService
}

type ServiceType = keyof ServiceTypeMapping;

function getService<T extends ServiceTypeMapping, K extends keyof ServiceTypeMapping>(serviceType : K): typeof T[K]{
    switch(serviceType){
        case 'Keyboard':
            return new KeyboardService();
        case 'Mouse':
            return new MouseService();
    }
    throw new Error("No implementation error");
}

//This should be an error
const mouseService = getService('Keyboard');


我正在传递键盘并期待 IKeyboardService。目前,这在 getService 的返回类型上出错。

你可以在这里玩:https://stackblitz.com/edit/typescript-leut1x

谢谢。

【问题讨论】:

  • 您可以删除 T 并只使用 function getService&lt;K extends keyof ServiceTypeMapping&gt;(serviceType: K): ServiceTypeMapping[K] { 但键入实现很棘手

标签: typescript type-inference


【解决方案1】:

你可以使用overloads:

function getService(serviceType: 'Keyboard'): KeyboardService;
function getService(serviceType: 'Mouse'): MouseService;
function getService(serviceType: keyof ServiceTypeMapping): ServiceTypeMapping[keyof ServiceTypeMapping] {
    switch(serviceType){
        case 'Keyboard':
            return new KeyboardService();
        case 'Mouse':
            return new MouseService();
        default:
            throw new Error("No implementation error");
    }
}

Typescript Playground

【讨论】:

    【解决方案2】:

    您也可以在返回时使用条件类型:

    function getService<T extends ServiceType>(serviceType: T) {
        let returnService
        switch(serviceType){
            case 'Keyboard':
                returnService = new KeyboardService();
                break;
            case 'Mouse':
                returnService = new MouseService();
                break;
            default:
                throw new Error("No implementation error");
        }
        return returnService as T extends 'Keyboard' ? KeyboardService : MouseService
    }
    

    Playground

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-17
      • 2020-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-23
      • 2021-07-18
      • 1970-01-01
      相关资源
      最近更新 更多