[英]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 likeT
.这就是 [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)
}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.