I have a data
property inside of an object I'm looking to type in Typescript. It looks like the following:
type MyThing = {
data: {
options: {
myKey: string,
myValue: string
}[],
key: 'myKey',
value: 'myValue'
}
}
I would like to be able to instantiate types of this structure using a generic but can't quite wrap my mind around what I should be doing. Here are the requirements:
key
andvalue
are the base "keys" that must be supplied, but there may be others:description
for instanceoptions
should always be an array of objects containing only the values of thekey
,value
, and possiblydescription
defined below
I have no problems typing this literally (like in the above example). But if I want to supply custom keys and values ("myKey" and "myValue" respectively), or if I want to specify other options like a description beyond the key and value, I cannot figure out how to do such.
The desired solution would be for me to do something like this:
type MyThing = {
data: DataComposer<['key', 'value']>
// data: DataComposer<['key', 'value', 'description', ...]>
}
CodePudding user response:
I think you want a type like this:
type DataComposer<
K extends string,
V extends string,
OtherKeys extends Record<string, string> = Record<never, string>
> = {
data: {
options: { [optionKey in K | V | OtherKeys[keyof OtherKeys]]: string}[],
key: K,
value: V,
} & { [OtherKey in keyof OtherKeys]: OtherKeys[OtherKey] }
}
Here K
is the string literal for the key
and V
is for the value
. Then it accepts a third parameter for a mapping of other custom properties.
Which you use like this:
type MyThing = DataComposer<'myKey', 'myValue'>
/*
type MyThing = {
data: {
options: {
myKey: string;
myValue: string;
}[];
key: "myKey";
value: "myValue";
};
}
*/
type MyThingWithOther = DataComposer<'myKey', 'myValue', { foo: 'myFoo' }>
/*
type MyThingWithOther = {
data: {
options: {
myKey: string;
myValue: string;
myFoo: string;
}[];
key: "myKey";
value: "myValue";
foo: 'myFoo';
};
}
*/