简体   繁体   English

如何正确推断 typescript 中的类型

[英]How to properly infer type in typescript

I'm pretty new to typescript, this was probably answered before, but I can't find the answer anywhere, so here is the problem I'm trying to solve.我是 typescript 的新手,这可能以前已经回答过,但我无法在任何地方找到答案,所以这是我要解决的问题。

I have an enum我有一个枚举

enum TableNames = {
  example: 'example'
  example2: 'example2',
}

and I have these types for my models我的模型有这些类型

type TableName = keyof typeof TableNames

type TableState<L =any> = {
  list: Array<L>
}

type ExampleDataType = {
  id: string
  ...
}

type ExampleData2Type = {
  id: number
  ...
}

type TableStateType = {
  example: TableState<ExampleDataType>
  example2: TableState<ExampleData2Type>
}

type InterListType<TName extends TableName> = TableStateType[TName]['list'][number]

and I have this special function我有这个特殊的 function

const createPath = <TName extends TableNames, T = InferListType<TName>>(
  tableName: TName,
  record: T
) => {
  if (tableName === TableNames.example) {
    console.log(record) // how to get this to infer to "ExampleDataType"
  }

  if (tableName === TableNames.example2) {
    console.log(record) // how to get this to infer to "ExampleData2Type"
  }
}

The question is the comment above, right now I'm getting this问题是上面的评论,现在我明白了

if (tableName === TableNames.example) {
  console.log(record) // T = InferListType<TName>
}

NOTE: typescript version is 3.7.4注意:typescript 版本为 3.7.4

You are running into this issue: Typescript - How do I narrow type possibilities of a generic type in a switch statement?您遇到了这个问题: Typescript - 如何在 switch 语句中缩小泛型类型的可能性? . .

Here's why [it] won't work: Typescript has control-flow type narrowing for variables like tableName , but not for type parameters like T .这就是 [it] 不起作用的原因:Typescript 对tableName之类的变量进行了控制流类型缩小,但对T之类的类型参数则没有。

JCalz mentions a workaround in the comments that might help. JCalz 在评论中提到了一个可能有帮助的解决方法。 Looks something like this:看起来像这样:

type ExampleDataType = {
  id: string
  data1: string
}

type ExampleDataType2 = {
  id: string
  data2: string
}

type TableToRecordMap = {
  example: ExampleDataType
  example2: ExampleDataType2
}

type TableName = keyof TableToRecordMap

type TableState<L =any> = {
  list: Array<L>
}

type TableStateType = {
  [Table in TableName]: TableState<TableToRecordMap[Table]>
}

const createPath = <TName extends TableName>(
  tableName: TName,
  record: TableToRecordMap[TName]
) => {
  const partialTable: Partial<TableToRecordMap> = { [tableName]: record };

  if (partialTable.example) {
    console.log(partialTable.example)
  } else if (partialTable.example2) {
    console.log(partialTable.example2)
  }
};

Playground link 游乐场链接

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

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