I’ve got a type defined as:
type Response = 'n_a' | 'n_o' | 'yes' | 'no'
I’d like to have a type that enforces that underscores are replaced with slashes:
type ReplaceUnderscoreWithSlash<T extends string> =
T extends `${infer Head}_${infer Tail}` ? `${Head}/${Tail}` : T;
Everything works as expected here:
type HumanReadableResponses = ReplaceUnderscoreWithSlash<Response>;
Now, I’d like to create a lookup object that I can use at runtime to convert from the underscore versions to the "human readable" versions but I’d like for the association to be typesafe.
I tried writing this as
type LookupObject<T extends string> = Record<T, ReplaceUnderscoreWithSlash<T>>;
However, this doesn’t provide key -> value type safety like I was hoping to achieve since this appears to be valid:
const lookupObject: LookupObject<Response> = {
n_a: 'n/a',
n_o: 'n/a', // <---- I'd like it if this threw an error because the only valid value should be 'n/o'
no: 'no',
yes: 'yes',
};
Is what I’m trying to accomplish here possible?
>Solution :
You need to corelate each key with the / version of the key. You can do this with a custom mapped type:
type LookupObject<T extends string> = {
[P in T] : ReplaceUnderscoreWithSlash<P>
}
const lookupObject: LookupObject<Response> = {
n_a: 'n/a',
n_o: 'n/a', // error
no: 'no',
yes: 'yes',
};