There's a couple of questions related to this but none I could find that match my requirements.
I wish to create a factory that, based on the type, requires a factory for each key of that object that contains the value and the entire object. For example:
type Row = {
foo: string
bar: number
baz: unknown
}
const factory: MyMagicType<Row> = [{
field: 'foo',
// Infers value as string
factory: (value, obj) => ..
}, {
field: 'bar',
// Infers value as number
factory: (value, obj) => ..
}]
^also throws that 'baz' hasn't been populated
I have tried using generics for this but got stuck.
type MyMagicType<TObj extends Record<string, unknown>, TField extends keyof TObj> {
field: TField,
factory: (val: TObj[TField], source: TObj) => any
}[]
But this doesn't work due to the field needing to be inferred rather than passed into the generic.
How can I omit the TField
but still let it infer from field
?
CodePudding user response:
Not sure how you want to type the second parameter and the return value of your factory functions, but here is a possible implementation of MyMagicType
that types the first parameter correctly:
type Row = {
foo: string
bar: number
baz: unknown
};
type MyMagicType<T extends object> = Array<{
[K in keyof T]: {
field: K,
factory: (value: T[K], obj: any) => any,
}
}[keyof T]>;
const factory: MyMagicType<Row> = [{
field: 'foo',
// Infers value as string
factory: (value, obj) => undefined
}, {
field: 'bar',
// Infers value as number
factory: (value, obj) => undefined
}];