I have this function that I’m trying to convert from js to ts, I thought that the type of the variable hi will be ('s'|'bb')[] but actually it’s string[]. How can I get typescript to infer K to be the keys of NewOptions?
export const getWithOverrides = <
K extends string,
NewOptions extends { [x in K]?: boolean },
Overrides extends { [x in K]?: boolean }
>(
newOptions: NewOptions,
overrides: Overrides
): K[] =>
(Object.keys(newOptions) as K[]).filter(key => {
if (typeof overrides[key] === 'boolean') {
return overrides[key];
}
return newOptions[key];
});
const hi = getWithOverrides({ s: true, bb: true }, { s: true });
>Solution :
You can do that by removing the K type parameter, requiring that the object types extend Record<string, boolean>, and using keyof with your two object types:
export const getWithOverrides = <
NewOptions extends Record<string, boolean>,
Overrides extends Record<string, boolean>
>(
newOptions: NewOptions,
overrides: Overrides
): (keyof NewOptions | keyof Overrides)[] =>
Object.keys(newOptions).filter((key) => {
if (typeof overrides[key] === "boolean") {
return overrides[key];
}
return newOptions[key];
});
const hi = getWithOverrides({ s: true, bb: true }, { s: true });
// ^? const hi: ("s" | "bb")[]