typescript 类型求助

2022-04-27 12:17:30 +08:00
 nulIptr
二手前端写 react 组件的时候遇到的问题
先贴代码
https://gist.github.com/nulIptr/7cc0a421a6e91db3336973cae4c07326


useTableWithCustomKey 的第二个参数 keyName 的类型应该是 T 中所有类型是 string 类型的字段名称。
然后用 useTableForName 这种形式调用是没问题的
但是用 useTable 这种再套一个 T extends { name: string },然后传入 name 就不行了,报错是
Argument of type 'string' is not assignable to parameter of type 'keyof StringOnly<T>'.
Type '"name"' is not assignable to type '(T[K] extends string ? K : never) | (T["name"] extends string ? "name" : never)'.ts(2345)


请问怎样才能消除这个报错。
原始需求是写一个 table 组件,有的对象是用 name 做 key ,有的是用 id 做 key
再贴一个
https://codesandbox.io/s/ts-playground-forked-qgnqhg?file=/src/index.ts
方便大佬们在线测试
1847 次点击
所在节点    TypeScript
4 条回复
gydi
2022-04-27 13:04:50 +08:00
我改成这样就可以了

function useTableWithCustomKey<T, K = keyof StringOnly<T>>(
records: T[],
keyName: K,
) {}
noe132
2022-04-27 13:06:56 +08:00
研究了半天,我找到一个可能是答案的答案
typescript 目前不支持 partial type parameter inference
https://stackoverflow.com/questions/64376774/in-typescript-how-can-i-infer-my-arguments-and-impose-a-constraint-that-all-ite

function useTable<T extends { name: string }>(records: Array<T>) {
type IsNameInKeys = 'name' extends keyof T ? true : false

const a: IsNameInKeys = true;
const b: IsNameInKeys = false;

return useTableWithCustomKey(records, 'name');
}
这个地方 是不是看起来 IsNameInKeys 不是 true 就是 false ?然而 变量 a 和 b 的类型检查都无法通过。
noe132
2022-04-27 13:08:25 +08:00
所以要么所有类型都是具体类型,要么所有类型都是类型参数。1 楼这个例子就是把 keyName 提升到了类型参数
nulIptr
2022-04-27 15:20:56 +08:00
@gydi 这种形式相当于完全没限制 k 的类型呀,函数体里面也不能直接用 records[keyName]了,如果改成下面这样有和我贴出的代码一致了
function useTableWithCustomKey<T, K extends keyof StringOnly<T>>(
records: T[],
keyName: K,
) {}



@noe132 所以看起来就是目前还不能解决这个问题是吧。感觉很奇怪。。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/849541

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX