[英]TS - infer on key without getting union type
here is a playground:这是一个游乐场:
https://www.typescriptlang.org/play?target=9#code/C4TwDgpgBAjlC8UDeBYAUFKBtA1hEAXFAM7ABOAlgHYDmAukahplAPYBGAVgIxECGVEABp0LNlwBM-QWPQBfOenQBjVlVKwArgmSjYU3c0wceRAOTAIpMyKPjOBi1eASzstHNuYYAZkZ7jLl4oCS8WEwMJHwAWdwUlNBU1DRhNCDIQADEqHQAeABUoCAAPSyoAE2JYAD4AChMifIBKBGqoXIBpItKICqq8EFYAMyh8upgiDqbGrA66LDMTbjM6VsNMVXVgZCWhewk5HRMsGDo9MghgTTIcpfkEjeTt1LIdVPSsqlrUpoTNjWIrAAthBWMAABbpIY5RC1PhkGhEAAK8L4IMsZGIuVAkGGWjI1SwAAY6C14G0mJgADaXKAXYhEABKl2uVHy4Ag2I5eJeXNxI3hNGq1XOVje1zhCN+zAuVxudKs90SaH+23pOkBILBkLI0NqZl8ZhaAHpjVAaBQAG7UGhQEFQPhQTRUChqKDUUgQPjlNgjahDdKUWhQVRkC7KbY4iAJdBAA https://www.typescriptlang.org/play?target=9#code/C4TwDgpgBAjlC8UDeBYAUFKBtA1hEAXFAM7ABOAlgHYDmAukahplAPYBGAVgIxECGVEABp0LNlwBM-QWPQBfOenQBjVlVKwArgmSjYU3c0wceRAOTAIpMyKPjOBi1eASzstHNuYYAZkZ7jLl4oCS8WEwMJHwAWdwUlNBU1DRhNCDIQADEqHQAeABUoCAAPSyoAE2JYAD4AChMifIBKBGqoXIBpItKICqq8EFYAMyh8upgiDqbGrA66LDMTbjM6VsNMVXVgZCWhewk5HRMsGDo9MghgTTIcpfkEjeTt1LIdVPSsqlrUpoTNjWIrAAthBWMAABbpIY5RC1PhkGhEAAK8L4IMsZGIuVAkGGWjI1SwAAY6C14G0mJgADaXKAXYhEABKl2uVHy4Ag2I5eJeXNxI3hNGq1XOVje1zhCN+zAuVxudKs90SaH+23pOkBILBkLI0NqZl8ZhaAHpjVAaBQAG7UGhQEFQPhQTRUChqKDUUgQPjlNgjahDdKUWhQVRkC7KbY4iAJdBAA
Basically having a function where I can send in an argument that returns some value.基本上有一个 function,我可以在其中发送一个返回一些值的参数。 It gives me a union however since there are keys with the same name that have different types:
但是,它给了我一个联合,因为存在具有不同类型的相同名称的键:
const qu = {
q2: {
obj1: 'test',
obj2: 'test2'
},
q3: {
obj1: 2,
obj2: 234
}}
is there a way to infer the type?有没有办法推断类型? I've tried with conditionals but with no luck.
我试过条件语句但没有运气。 Or is this a TS limitation?
或者这是 TS 限制?
Here is full code example:这是完整的代码示例:
type q = {
[key: string]: {
obj1: any,
obj2: any
}}
const qu = {
q2: {
obj1: 'test',
obj2: 'test2'
},
q3: {
obj1: 2,
obj2: 234
}}
const queryFn = <T extends q>(obj: T) => <K extends keyof T>(q: K): T[K]['obj1'] => {
const {obj1, obj2} = obj[q]
return obj1
}
const qur = queryFn(qu)
const someotherfn = (arg: Parameters<typeof qur>[0]) => {
let res: ReturnType<typeof qur<typeof arg>>
res = qur(arg)
return res
}
const res = someotherfn('q3') // giving me a union instead of inferring correct type
The problem here is that someotherfn
is not itself generic ;这里的问题是
someotherfn
本身不是通用的; if you don't explicitly annotate the call signature as generic, then the return type someotherfn
will not depend on its input type.如果您没有将调用签名显式注释为通用,则返回类型
someotherfn
将不依赖于其输入类型。
The fix could look like this:修复可能如下所示:
const someotherfn = <K extends Parameters<typeof qur>[0]>(arg: K) => {
let res: ReturnType<typeof qur<K>>
res = qur(arg)
return res
}
where we just make the function generic in K
, the type of arg
.我们只是在
K
中使 function 成为泛型,即arg
的类型。 Now things behave as expected:现在事情按预期进行:
const res = someotherfn('q3');
// const res: number
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.