首页 > 解决方案 > Typescript 重载类型 boolean 不能分配给 false 类型

问题描述

我有一个基于选项键值返回不同类型的方法。

class Test {
  getData(options: { obj: true }): Object;
  getData(options: { obj: false }): any[];
  getData(): any[];
  getData(options = { obj: false }): Object | any[] {
    if (options.obj) {
      return {};
    } else {
      return [];
    }
  }
}

传递objastrue时,我将返回对象,否则返回数组。这很好用。

const instance = new Test();
const result = instance.getData({ obj: true }); // inffered as array
const result2 = instance.getData(); // inffered as object

问题是当我需要使用动态值时会引发错误:

boolean 类型不能分配给 false 类型

function getResult(obj: boolean = false ) {
  return instance.getData({ obj });
}

问题是什么?

标签: javascripttypescript

解决方案


由于{ obj }{ obj: boolean }在编译时知道的类型,编译器不知道选择任何重载,因此您必须显式提供一个重载{ obj: boolean }(因为实现签名不计为函数的公共签名) ,在这种情况下编译器不会做任何魔术:

class Test {
    getData(options: { obj: true }): Object;
    getData(options: { obj: false }): any[];
    getData(options: { obj: boolean }): Object | any[];
    getData(): any[];
    // This signature is the implementation and is not conidered when resolving the method 
    getData(options = { obj: false }): Object | any[] {
        if (options.obj) {
            return {};
        } else {
            return [];
        }
    }
} 

编辑

您还可以在方法签名中使用条件类型,这将减少签名的数量:

class Test {
    getData<T extends boolean>(options: { obj: T }): T extends true ? Object : any[];
    getData(): any[];
    // This signature is the implementation and is not conidered when resolving the method 
    getData(options = { obj: false }): Object | any[] {
        if (options.obj) {
            return {};
        } else {
            return [];
        }
    }
}


const instance = new Test();
const result = instance.getData({ obj: true }); // inffered as array
const result2 = instance.getData(); // inffered as object

function getResult(obj: boolean = false) {
    return instance.getData({ obj }); // inferred as Object|any[]
}

由于type boolean = true | false和条件类型分布在联合上, T extends true ? Object : any[];将是Object|any[]when Tis boolean。什么时候Ttrue回报Object,什么时候Tfalse回报,any一切如期而至


推荐阅读