【发布时间】:2021-07-07 17:05:17
【问题描述】:
我在将条件类型与计算对象属性名称结合使用时遇到问题。基本上我是根据输入字符串将行插入到数据库中。然后我根据该输入字符串键入返回对象。返回对象中的属性之一是计算名称,该名称也基于输入字符串。因此,打字稿似乎拥有验证这是否正确所需的所有信息,但它不断给我错误。这是一个非常简化的示例。
//types of the table rows from the database
interface FirstTableRow {
id: number,
someFirstRefId: number
};
interface SecondTableRow {
id: number,
someSecondRefId: number
};
//maps which table we're working with to its reference column name
const whichToExtraColumn = {
first: 'someFirstRefId',
second: 'someSecondRefId'
} as const;
//maps the table to the returned row type
type ConstToObj<T> = (T extends 'first'
? FirstTableRow
: T extends 'second'
? SecondTableRow
: never
);
function createFirstOrSecond<
T extends keyof typeof whichToExtraColumn
>(
which: T
): ConstToObj<T> {
//gets the reference column name for this table
const refColumn = whichToExtraColumn[which];
//do database stuff....
const insertId = 1;
//build the inserted row
const test: ConstToObj<T> = {
id: insertId,
[refColumn]: 123
};
// ^ Type '{ [x: string]: number; id: number; }' is not assignable to type 'ConstToObj<T>'
return test;
};
我通过对refColumn 进行if-check 来解决此问题,然后根据它生成不同的对象。但是使用计算属性名称会更容易。任何帮助将不胜感激。
【问题讨论】:
-
我认为 Typescript 编译器运行的问题是
"first" | "second"是keyof typeof whichToExtraColumn的有效子类型,所以ConstToObj<T>可能是FirstTableRow | SecondTableRow并且对象不能分配给它.不幸的是,错误消息很短,所以很难说到底为什么会出现这种不匹配(以上是猜测) -
@JonasWilms,嗯,好点。关于如何更改函数以使用条件的任何想法?我已经尝试了很多,但似乎无法正常工作。
标签: javascript typescript computed-properties conditional-types