【发布时间】:2018-09-24 21:12:46
【问题描述】:
在遇到 TS 2.6 中的问题后,我一直在尝试使用 TypeScript 2.8 的条件类型,但遇到了一个我不理解的错误,可以寻求帮助:
这个例子涉及到解决这个问题。
export class Column<T> {
readonly base: T
constructor(base: T) {
this.base = base
}
}
export class ColumnExpression<E, CT, CK extends Column<CT>> {
readonly table: TableExpression<E>
readonly column: CK
alias?: string
constructor(table: TableExpression<E>, column: CK, alias?: string) {
this.table = table
this.column = column
this.alias = alias
}
}
type Table<E> = {
[P in keyof E]: E[P] extends (infer U) ? Column<U> : never
}
type TableQuery<E> = {
[P in keyof E]: E[P] extends Column<(infer CT)> ? ColumnExpression<E, CT, E[P]> : never
}
export class TableExpression<E> {
readonly table: Table<E>
alias?: string
constructor(table: Table<E>, alias?: string) {
this.table = table
this.alias = alias
}
}
function toTable<E>(target: E): Table<E> {
let result = {} as Table<E>
for (const k in target) {
result[k] = new Column(target[k])
}
return result
}
function toTableExpression<E>(target: E): TableExpression<E> {
const table = toTable(target)
return new TableExpression(table)
}
function toTableFilter<E>(target: TableExpression<E>): TableQuery<E> {
let result = {} as TableQuery<E>
let table = target.table
for (const k in table) {
result[k] = new ColumnExpression(target, table[k])
}
return result
}
class Test {
id: number
name: string
createdAt: Date
createdById: number
}
let contentTable = toTable(new Test())
let contentFilter = toTableFilter(new TableExpression(contentTable))
contentTable.id.base
contentTable.name.base
在第 56 行弹出确切的错误:
result[k] = new ColumnExpression(target, table[k])
错误:
(56,46): error TS2345: Argument of type 'Table<E>[keyof E]' is not assignable to parameter of type 'Column<{}>'.
Type 'Column<E[keyof E]>' is not assignable to type 'Column<{}>'.
Type 'E[keyof E]' is not assignable to type '{}'.
1:57:46 PM - Compilation complete. Watching for file changes.
在 TS 2.6 中,我基于索引类型访问(根据其他人对 SO 的建议)为 ColumnExpression 使用了不同的类型定义,作为参考,它被定义为:
type TableQuery<TK extends TableLike> = {
[P in keyof TK]: Column.ColumnExpression<TK, TK[P]['base'], TK[P]>
}
TK[P]['base'] 允许我访问底层列类型,但这种方法从 TS 2.7 开始不再适用。目前尚不清楚这是否是一个错误。我已经阅读了一些似乎相关但没有解决这个确切问题的 GH 问题。我希望 2.8 中引入的条件类型能让我更干净地解决这个问题,但到目前为止,运气不佳。
任何想法将不胜感激。
【问题讨论】:
-
你的类型很混乱;
contentFilter是无意义的类型TableQuery<Test>,一盒never。如果您的意思是TableQuery<Table<Test>>,那么您的toTableFilter()定义是错误的。请仔细检查您的类型,并可能添加有关类型应该是什么的 cmets?也许类型参数名称有一些一致性? (E在某些地方似乎是“任何类型”,而在其他地方则是“Column属性的记录”)。现在,每当我开始解决您的问题(类型参数推断失败)时,TypeScript 都会立即抱怨其他问题。
标签: typescript mapped-types conditional-types