'Typescript object literal narrowing
I've been googling for close to two hours so now I turn to Stack Overflow for help. I am writing a function which accepts an object parameter. I can't figure out how to force TS to narrow to the type when an object literal is passed. My simple working example looks like the code below but it feels unnecessarily cumbersom:
type ValueOf<T> = T[keyof T];
const getRandomValue = <T, S=Record<string, T>>(obj:S):T => {
const values = Object.values(obj);
const randomIndex = Math.floor(Math.random() * values.length);
return values[randomIndex];
}
const obj = {
a: "hi",
b: "hello",
} as const;
//this works as expected but it's cumbersome to define the literal separately and have to say "as const" to avoid the type becoming { string: string }
const value = getRandomValue<ValueOf<typeof obj>>(obj);
//prove that it works
type ValueType = typeof value;
const x:ValueType = "hello"; //allowed
const y:ValueType = "bonjour"; //shows a type error
//I was hoping I could define the function in a way where I could call it like this and still
//get the same strict typing as above: getRandomValue({ a: "hi", b: "hello" });
Edit: removed the non-working version of code.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
