Let's do it in O(1) ...
Given generic invariant function -
function invariant(condition: unknown, message?: string): asserts condition {
if (condition) return
throw Error(`Invariant violation: ${message ?? "truthy value expected"}`)
}
Write invariantLanguage using keyof typeof Language -
function invariantLanguage(lang: string): asserts lang is keyof typeof Language {
invariant(lang in Language, `"${lang}" is not a valid language`)
}
Now you can use invariantLanguage on your string input -
// ...
enum Language {
nl = 1,
fr = 2,
en = 3,
de = 4,
}
const x = "en"
invariantLanguage(x)
console.log(x) // : "en"
const y = "foo"
invariantLanguage(y) // ERROR Invariant violation: "foo" is not a valid language
console.log(y) // : never
Verify on typescript playground.
It is also demonstrated working properly with string enums -
// ...
enum Language {
nl = 1,
fr = 2,
en = 3,
de = 4,
ja = "japanese", // also works if you have strings
}
const x = "ja"
invariantLanguage(x)
console.log(x) // : "ja"
Notice is does not mistake a value for a key -
const y = "japanese"
invariantLanguage(y) // ERROR Invariant violation: "japanese" is not a valid language
console.log(y) // : never
Verify on typescript playground.