【发布时间】:2019-06-17 22:57:31
【问题描述】:
我有以下类型定义。
type Key<Row> = {
[P in keyof Row]: Row[P] extends string ? P : never
}[keyof Row];
type ID<Row> = Row[Key<Row>];
type Selected<Row> = {
selected: boolean;
} & Row;
Key<Row> 返回Row 的所有属性键,其值为字符串。 See this answer 了解它的构造方式。
ID<Row> 是Row 的所有字符串值的并集。它始终是string,但如果字符串值是字符串常量,则可以很好地缩小范围,例如在
interface X {
prop: "abc";
}
ID<X> 始终是"abc"。
Selected<Row> 是 Row 加上属性 selected: boolean 的交集类型。
以上都定义好了,我不明白为什么下面的函数定义会抛出错误:
const getId = <Row>(row: Selected<Row>, key: Key<Row>): ID<Selected<Row>> =>
row[key];
TS 给我的类型错误粘贴在下面,但我不知道为什么 TS 不喜欢我的代码。
据我所见,row[key] 应该始终有效,因为即使 row 是 Selected<Row>,Key<Row> 只包含一组更窄的键,那么键入具有更多属性的对象有什么问题我们实际使用的密钥?
Here is a link to the TS playground with this code showing the error
Type 'Selected<Row>[{ [P in keyof Row]: Row[P] extends string ? P : never; }[keyof Row]]' is not assignable to type '{ selected: boolean; }[(Selected<Row>[keyof Row] extends string ? keyof Row : never) & (Selected<Row>["selected"] extends string ? "selected" : never)] & Row[(Selected<Row>[keyof Row] extends string ? keyof Row : never) & (Selected<...>["selected"] extends string ? "selected" : never)]'.
Type 'Selected<Row>[Row[keyof Row] extends string ? keyof Row : never]' is not assignable to type '{ selected: boolean; }[(Selected<Row>[keyof Row] extends string ? keyof Row : never) & (Selected<Row>["selected"] extends string ? "selected" : never)] & Row[(Selected<Row>[keyof Row] extends string ? keyof Row : never) & (Selected<...>["selected"] extends string ? "selected" : never)]'.
Type 'Selected<Row>[keyof Row]' is not assignable to type '{ selected: boolean; }[(Selected<Row>[keyof Row] extends string ? keyof Row : never) & (Selected<Row>["selected"] extends string ? "selected" : never)] & Row[(Selected<Row>[keyof Row] extends string ? keyof Row : never) & (Selected<...>["selected"] extends string ? "selected" : never)]'.
Type 'Row[string] | Row[number] | Row[symbol]' is not assignable to type '{ selected: boolean; }[(Selected<Row>[keyof Row] extends string ? keyof Row : never) & (Selected<Row>["selected"] extends string ? "selected" : never)] & Row[(Selected<Row>[keyof Row] extends string ? keyof Row : never) & (Selected<...>["selected"] extends string ? "selected" : never)]'.
Type 'Row[string]' is not assignable to type '{ selected: boolean; }[(Selected<Row>[keyof Row] extends string ? keyof Row : never) & (Selected<Row>["selected"] extends string ? "selected" : never)] & Row[(Selected<Row>[keyof Row] extends string ? keyof Row : never) & (Selected<...>["selected"] extends string ? "selected" : never)]'.
Type 'Row[string]' is not assignable to type '{ selected: boolean; }[(Selected<Row>[keyof Row] extends string ? keyof Row : never) & (Selected<Row>["selected"] extends string ? "selected" : never)]'.
Type 'Row' is not assignable to type '{ selected: boolean; }'.
Type 'Row[string]' is not assignable to type 'boolean'.
Type 'Selected<Row>[keyof Row]' is not assignable to type '{ selected: boolean; }[(Selected<Row>[keyof Row] extends string ? keyof Row : never) & (Selected<Row>["selected"] extends string ? "selected" : never)]'.
Type 'keyof Row' is not assignable to type '(Selected<Row>[keyof Row] extends string ? keyof Row : never) & (Selected<Row>["selected"] extends string ? "selected" : never)'.
Type 'keyof Row' is not assignable to type 'Selected<Row>[keyof Row] extends string ? keyof Row : never'.
Type 'Selected<Row>[keyof Row]' is not assignable to type 'boolean'.
Type 'Selected<Row>[Row[keyof Row] extends string ? keyof Row : never]' is not assignable to type '{ selected: boolean; }[(Selected<Row>[keyof Row] extends string ? keyof Row : never) & (Selected<Row>["selected"] extends string ? "selected" : never)]'.
Type 'Row[keyof Row] extends string ? keyof Row : never' is not assignable to type '(Selected<Row>[keyof Row] extends string ? keyof Row : never) & (Selected<Row>["selected"] extends string ? "selected" : never)'.
Type 'Row[keyof Row] extends string ? keyof Row : never' is not assignable to type 'Selected<Row>["selected"] extends string ? "selected" : never'.
Type 'Selected<Row>[Row[keyof Row] extends string ? keyof Row : never]' is not assignable to type 'boolean'.
Type 'Selected<Row>[{ [P in keyof Row]: Row[P] extends string ? P : never; }[keyof Row]]' is not assignable to type '{ selected: boolean; }[(Selected<Row>[keyof Row] extends string ? keyof Row : never) & (Selected<Row>["selected"] extends string ? "selected" : never)]'.
Type 'Row[keyof Row] extends string ? keyof Row : never' is not assignable to type '(Selected<Row>[keyof Row] extends string ? keyof Row : never) & (Selected<Row>["selected"] extends string ? "selected" : never)'.
Type 'keyof Row' is not assignable to type '(Selected<Row>[keyof Row] extends string ? keyof Row : never) & (Selected<Row>["selected"] extends string ? "selected" : never)'.
Type 'string | number | symbol' is not assignable to type '(Selected<Row>[keyof Row] extends string ? keyof Row : never) & (Selected<Row>["selected"] extends string ? "selected" : never)'.
Type 'string' is not assignable to type '(Selected<Row>[keyof Row] extends string ? keyof Row : never) & (Selected<Row>["selected"] extends string ? "selected" : never)'.
Type 'string' is not assignable to type 'Selected<Row>[keyof Row] extends string ? keyof Row : never'.
Type 'keyof Row' is not assignable to type 'Selected<Row>[keyof Row] extends string ? keyof Row : never'.
Type 'string | number | symbol' is not assignable to type 'Selected<Row>[keyof Row] extends string ? keyof Row : never'.
Type 'string' is not assignable to type 'Selected<Row>[keyof Row] extends string ? keyof Row : never'.
Type 'Row[keyof Row] extends string ? keyof Row : never' is not assignable to type 'Selected<Row>["selected"] extends string ? "selected" : never'.
Type 'Selected<Row>[{ [P in keyof Row]: Row[P] extends string ? P : never; }[keyof Row]]' is not assignable to type 'boolean'.
Type 'Selected<Row>[Row[keyof Row] extends string ? keyof Row : never]' is not assignable to type 'boolean'.
Type 'Selected<Row>[keyof Row]' is not assignable to type 'boolean'.
Type 'Row[string] | Row[number] | Row[symbol]' is not assignable to type 'boolean'.
Type 'Row[string]' is not assignable to type 'boolean'.
【问题讨论】:
标签: typescript