Reputation: 723
I'm trying to create a few generic recursive types to modify structure of existing types. I can't tell why the sections inferring arrays and nested objects is not getting triggered. Any idea what I'm doing wrong?
TS playround link with the below code:
//Generics
type WithConfidence<T> = {
[Property in keyof T]: {
value: FieldWithConfidence<T[Property]>;
confidence: number;
};
};
type FieldWithConfidence<T> = {
[P in keyof T]: T[P] extends string | number | Date
? T[P]
: T[P] extends Array<infer U>
? {
confidence: number;
value: Array<WithConfidence<U>>;
}
: {
value: FieldWithConfidence<T[P]>;
confidence: number;
};
};
It works for primitive types and when the type is an object, just not an array. Here's an example illustrating where it falls short.
type Asset = {
AssetCode?: string;
Contracts?: Array<Contract>;
Warranty: WarrantyInfo;
};
type Contract = {
ContractNumber: string;
};
type WarrantyInfo = {
Purchased: Date;
};
const value: WithConfidence<Asset> = {
Warranty: {
confidence: 500,
value: {
Purchased: {
value: new Date(), //Error
confidence: 500,
},
},
},
AssetCode: {
value: "123",
confidence: 100,
},
Contracts: {
confidence: 400,
value: [
{
ContractNumber: { //Error
value: "123",
confidence: 500,
},
},
],
},
};
Upvotes: 0
Views: 672
Reputation: 2099
Assuming what I mentioned in my comment on your question, the fix is just to simplify your FieldWithConfidence
type significantly. Right now it is trying to add a number of additional levels of structure beyond what you seem to want. Here is a version of that type that works as I think you intend:
type FieldWithConfidence<T> =
T extends boolean | string | number | Date
? T
: T extends Array<infer U>
? Array<FieldWithConfidence<U>>
: WithConfidence<T>;
Here's a working playground link with that change.
Upvotes: 3