对象文字具有函数时的Typescript错误

对象文字具有函数时的Typescript错误,typescript,Typescript,代码如下: function id<T>(x: T) { return x } const keys: string[] = [] const obj1 = Object.fromEntries(keys.map(k => [ k, {test() {}} // OK ])) const obj2 = Object.fromEntries(keys.map(k => [ k, id({test() {}}) // Erro

代码如下:

function id<T>(x: T) {
    return x
}

const keys: string[] = []

const obj1 = Object.fromEntries(keys.map(k => [
    k, 
    {test() {}} // OK
]))

const obj2 = Object.fromEntries(keys.map(k => [
    k, 
    id({test() {}}) // Error
]))

const obj3 = Object.fromEntries(keys.map(k => [
    k, 
    id({test: new Date()}) // OK
]))
似乎只有object literal中的函数才会导致此错误

这里的
id
函数仅用于演示。实际函数具有以下签名:

(x:T)=>T&SomeExtraFields

Typescript版本:4.2.3

立即尝试

function id<T>(x: T): T {
   return x
}

const keys: string[] = []

const obj1 = Object.entries(keys.map(k => [
    k,
    { test() { } } // OK
]))

const obj2 = Object.entries(keys.map(k => [
    k,
    id({ test() { } }) // Ok
]))

const obj3 = Object.entries(keys.map(k => [
    k,
    id({ test: new Date() }) // OK
]))
函数id(x:T):T{
返回x
}
常量键:字符串[]=[]
const obj1=Object.entries(keys.map)(k=>[
K
{test(){}//OK
]))
const obj2=Object.entries(keys.map)(k=>[
K
id({test(){}})//确定
]))
const obj3=Object.entries(keys.map)(k=>[
K
id({test:new Date()})//确定
]))

您有几种处理方法:

第一名:

如果使用引用而不是文字类型,则它将按预期工作:

const id=(x:T):T=>x
常量键:字符串[]=[]
const iter=keys.map(k=>[
K
id({test(){}})//确定
])
const obj2=Object.fromEntries(iter)
或:

const idResult=id({test(){})
const obj2=Object.fromEntries(keys.map)(k=>[
K
伊德里索
]))

让我们尝试使用arrow函数作为属性而不是方法:

const obj2=Object.fromEntries(keys.map)(k=>[
K
id({test:()=>{}})//确定
]))
奇怪的行为,不是吗

让我们看看
对象。fromEntries
签名:

fromEntries(entries:Iterable):{[k:string]:T};
因此,TS试图推断
T
泛型类型。在我们的例子中,它是
id函数的
ReturnType

但由于某种原因,TS无法做到这一点

第三名:

为了帮助TS推断类型,您可以为
Array.prototype.map

const obj2=Object.fromEntries(
key.map((k)=>[k,id({test(){}})])
);
第四

您也可以在不使用任何显式泛型参数的情况下处理它

您可以在
id
函数定义中将约束添加到
T
generic

接口方法{
():无效;
}
常数id=(x:T)=>x;
常量键:字符串[]=[];
const obj2=Object.fromEntries(keys.map((k)=>[k,id({test(){}]);//好啊
/////////////////////////
输入ArrowProp=()=>any;
常数id=(x:T)=>x;
常量键:字符串[]=[];
const obj2=Object.fromEntries(keys.map((k)=>[k,id({test(){}]);
第五名

您甚至可以使用第二个泛型来帮助TS推断类型

constid=(x:T)=>x;
//或
常数id=(x:T)=>x;
常量键:字符串[]=[];
const obj2=Object.fromEntries(keys.map((k)=>[k,id({test(){}]);

不幸的是,我无法解释为什么TS在没有任何解决方法的情况下无法推断方法属性

也许这是一个错误。顺便说一下,在第二个示例中,如果arrow函数接受任何参数,那么错误会再次显示。然后我将使用显式泛型类型。遗憾的是,因为我喜欢自动类型推断。是的,方法类型和属性与箭头函数之间可能存在一些不一致。你会在github上提出问题吗?我也可以提高。如果你能做到,我将不胜感激this@dhmk083这里有一个链接,因此可以跟踪问题
function id<T>(x: T): T {
   return x
}

const keys: string[] = []

const obj1 = Object.entries(keys.map(k => [
    k,
    { test() { } } // OK
]))

const obj2 = Object.entries(keys.map(k => [
    k,
    id({ test() { } }) // Ok
]))

const obj3 = Object.entries(keys.map(k => [
    k,
    id({ test: new Date() }) // OK
]))