typescript关于检索属性类型的写法问题
发布于 9 天前 作者 dislido 486 次浏览 来自 问答
class Funs {
  foo({ n, s }: { n: number, s: string }) {}
  bar({ s, b }: { s: string, b: boolean }) {}
}

const funs = new Funs();

function callFun<T extends keyof Funs> (name: T, ...params: Parameters<Funs[T]>) {
  return funs[name](params[0]);
}

callFun('bar', { b: true, s: 'sss'})

T"foo" | "bar", params[0]应该是根据T来确认是{ n: number, s: string }{ s: string, b: boolean }(从调用callFun时的代码提示中看是可以确认的)
下面调用函数时,funs[name]理论上应该可以确认到具体的函数是foo还是bar,但是到了传param的时候就报错了:

类型“{ s: any; b: any; } | { n: any; s: any; }”的参数不能赋给类型“{ n: any; s: any; } & { s: any; b: any; }”的参数。
  不能将类型“{ s: any; b: any; }”分配给类型“{ n: any; s: any; } & { s: any; b: any; }”。
    Property 'n' is missing in type '{ s: any; b: any; }' but required in type '{ n: any; s: any; }'.ts(2345)

ts好像在这里没法确认到函数和参数的具体类型,那么怎么写才能正确让ts识别出类型呢?

6 回复

能动态获取函数类型的?应该没有这么智能把

function callFun<T extends keyof Funs>(name: T, ...params: Parameters<Funs[T]>) {
    return funs[name].apply(funs, params);
}

这个就跟 any 一样了,或者把参数全部可选了,不过感觉怪怪的

@yviscool 这个不错。也有类型检查的。

@waitingsong 这是里面有问题,外面肯定是好的啊,感觉他是想在里面获得对应的类型,进行下一步操作

@yviscool 我觉得应该方便动态调用类实例的方法,只要外面类型检查能通过就行,不在乎内部具体(类型)细节。

@yviscool 感谢解答,我现在直接用params[0] as any

function callFun<O, M extends keyof O>(object: O, method: M, ...params: Parameters<O[M]>) {
}

callFun(funs, 'foo', { n: 1, s: 'sss' })
callFun(funs, 'bar', { s: 'zjl', b: true})

你那样就行,我这样他就推断不出来,

回到顶部