索引类型和通用函数值

时间:2019-02-24 05:12:43

标签: typescript

尝试以下语法时出现编译错误,但我不明白为什么它不起作用:

interface Param<O> {
    obj: O;
}
interface Dico {
    [key: string]: <O>(param: Param<O>) => Param<O>;
}
var x: Dico = {
    fnString: (param: Param<string>) => { return param; },
    fnNumber: (param: Param<number>) => { return param; }
};

这里是playground link

fnString和fnNumber上出现编译错误:

Type '(param: Param<string>) => Param<string>' is not assignable to type '<O>(param: Param<O>) => Param<O>'.
  Types of parameters 'param' and 'param' are incompatible.
    Type 'Param<O>' is not assignable to type 'Param<string>'.
      Type 'O' is not assignable to type 'string'.  

如果我在接口Dico上移动通用类型O,它可以工作,但是我不能像我想的那样使用其他类型:

enter image description here

我缺少什么?这是我无法克服的限制,还是有办法实现?

1 个答案:

答案 0 :(得分:2)

您定义为重新运行索引的函数是通用函数。泛型函数的类型参数由调用者决定,而不是由执行方式决定,因此只有泛型函数可以与泛型函数签名兼容。

您想要的是一个非通用函数,该函数会强制执行输入和输出之间的关系。您可以使用额外的功能来帮助进行推断:

interface Param<O> {
    obj: O;
}

type Dico < T > ={
    [K in keyof T]: (param: Param<T[K]>) => Param<T[K]>;
}

function createDisco<T>(o: Dico<T>) {
    return o;
}
var x = createDisco({
    fnString: (param: Param<string>) => { return param; },
    fnNumber: (param: Param<number>) => { return param; }
    fnNumberErr: (param: Param<number>) => { return null as Param<string>; }
})
相关问题