Я не думаю, что машинопись может следовать логике условного типа для извлечения T
. Вам необходимо изменить логику и принять тип узла в качестве параметра типа и вручную вытянуть тип данных из типа узла. Решение может выглядеть примерно так:
export abstract class Node { }
type AllNodeTypes = ArrayNode<any> | ObjectNode<any>
export type NodeDataType<T extends AllNodeTypes> = T['data']; // can be a conoditional type with infer if needed (ie if not all node types have a data field)
export type ObjectNodeDataType<T extends Record<keyof T, Field<AllNodeTypes>>> = {
[P in keyof T]:NodeDataType<T[P]['node']>
}
export class ObjectNode<TNode extends Record<keyof TNode, Field<AllNodeTypes>>> extends Node {
constructor(public fields: TNode) {
super()
}
public data: ObjectNodeDataType<TNode>
}
export class ArrayNode<TNode extends AllNodeTypes> extends Node {
public data: NodeDataType<TNode>[]
constructor(public ofType: TNode) {
super()
}
}
class Field<T extends Node> {
constructor(public node: T) { }
}
const User = new ObjectNode({})
const query = new ObjectNode({
user: new Field(User),
users: new Field(new ArrayNode(User))
})
query.fields.users.node.ofType.fields
query.fields.user.node.fields
query.data.user
query.data.users