类型“ {}”不可分配给类型“ T”

时间:2019-06-25 08:28:10

标签: typescript

-d' '
  

错误:类型'{}'无法分配给类型'T'。

im尝试提供默认值。即时通讯不试图给T默认类型。

我不确定是什么问题。

1 个答案:

答案 0 :(得分:5)

考虑以下示例

type A = { [prop: string]: any };
type B = { [prop: string]: any; prop1: string };

类型B是否扩展类型A?是的!

但是以下操作无效

let a: A = {};
let b: B = a; // Error

很明显,类型A缺少必需的属性prop1,因此变量a无法分配给变量b

您的功能存在相同的问题。当你做

function f1<T extends { [prop: string]: any }>(a: T = {}) {
    console.log(a);
}

编译器说对象{}无法分配给类型T。如果可行,您可以

f1<B>();  // a will equal to {} and misses required prop1

这看起来好像不是错误,因为在f1内部您只知道T extends { [prop: string]: any },而对prop1一无所知。但是请考虑是否要返回T

function f1<T extends { [prop: string]: any }>(a: T = {}): T {
    console.log(a);
    return a;
}

如果此代码有效,则会引入错误

let bb: B = f1<B>();  // Here bb will be equal to empty object
let s: string = bb.prop1;  // Compiler will not show error, as it thinks that bb has prop1 of type string. But in reality it is undefined.

因此,有以下解决方案可供考虑:

  1. 删除所有泛型。类型{ [prop: string]: any }本身是通用的,因此可能满足您的需求

    function f1(a: { [prop: string]: any } = {}) {
        console.log(a);
        return a;
    }
    
  2. 使a完全可选。在这种情况下,a可能等于undefined,编译器会知道。

    function f1<T extends { [prop: string]: any } = {}>(a?: T) {
        console.log(a);
    }
    

    如果返回a,编译器会告诉您应该返回联合类型(使用undefined)或签入函数体以确保a不是undefined。 / p>

  3. 在我看来,最坏的情况是按照建议使用类型转换

    function f1<T extends { [prop: string]: any }>(a: T = {} as T) {
        console.log(a);
    }
    

    但是要小心,不要忘记在这种情况下您可能会错过一些必需的属性。