This is the object I've got:
const translations = {
msg_hello: 'Hello',
msg_bye: 'Bye'
}
Also I have a function that looks like this:
const generateTranslation = (partialKey: string): keyof typeof translations {
return `msg_${partialKey}`;
}
is there a way to check if the generated translation key will be valid? For example:
generateTranslation('hello'); // good
generateTranslation('no'); // bad
CodePudding user response:
I don't think there is an automatic way to do this, for dynamic strings like that where keyof
won't retrieve them. But you could manually create a type that is a union of the valid values, and require that the partialKey
argument be of that type:
const translations = {
msg_hello: 'Hello',
msg_bye: 'Bye'
};
type validPartialKeys = 'hello' | 'bye';
const generateTranslation = function (partialKey: validPartialKeys): keyof typeof translations {
return `msg_${partialKey}`;
}
generateTranslation('hello'); // good
generateTranslation('no'); // bad
CodePudding user response:
First of all, you need extract allowed values from translations
. In order to do that, you need to make translations
immutable.
const translations = {
msg_hello: 'Hello',
msg_bye: 'Bye'
} as const;
Then, for the sake of readability, you can create helper type:
type Translations = typeof translations;
Thanks to template literals, you can infer the string which goes after underscore _
:
type GetSuffix<T> = keyof T extends `msg_${infer Suffix}` ? Suffix : never;
type Test = GetSuffix<Translations> // "hello" | "bye"
Now, you can apply the restiction:
const generateTranslation = <
Key extends GetSuffix<Translations>
>(partialKey: Key): `msg_${Key}` => `msg_${partialKey}`
Be aware that I have infered partialKey
with help of GetSuffix<Translations>
which helped me to apply explicit return type msg_${Key}
.
WHole example:
const translations = {
msg_hello: 'Hello',
msg_bye: 'Bye'
} as const;
type Translations = typeof translations;
type GetSuffix<T> = keyof T extends `msg_${infer Suffix}` ? Suffix : never
type Test = GetSuffix<Translations> // "hello" | "bye"
const generateTranslation = <
Key extends GetSuffix<Translations>
>(partialKey: Key): `msg_${Key}` => `msg_${partialKey}`
const result = generateTranslation('hello'); // good ---> "msg_hello"
generateTranslation('no'); // bad