简体   繁体   English

TS - 在不获取联合类型的情况下推断键

[英]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

Playground link to code 游乐场代码链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM