Is it possible to make the types below work? The issue seems to be that T
might have symbols. Is there a way to ignore them?
type MyAnimals = { name: "dog", fleas: 2 }
function GetKeys<T extends MyAnimals>(animal: T) {
type prefixedAnimal = {
// Type 'key' is not assignable to type 'string | number | bigint | boolean | null | undefined'.
[key in keyof T as `my${key}`]: T[key]
}
}
type prefixedAnimal = {
[key in keyof MyAnimals as `my${key}`]: MyAnimals[key]
}
I tried wrapping my T in an utility type to remove anything except strings, but it didn't fix it:
type OnlyStringKeys<T> = {
[key in keyof T]: key extends string ? T[key] : never;
}
CodePudding user response:
Yes i think your reasoning is correct. You can filter out any non string keys like this:
type MixedType = "yes" | 0 | "no" | "maybe" | false;
type StringsOnly<T> = T & string;
type Test = StringsOnly<MixedType>; // "yes" | "no" | "maybe"
In your case then:
type MyAnimals = { name: "dog"; fleas: 2 };
function GetKeys<T extends MyAnimals>(animal: T) {
type prefixedAnimal = {
// now correctly filters for string keys only
[key in keyof T & string as `my${key}`]: T[key];
};
}
Your type does not exclude non string keys:
type MyAnimalsReloaded = { name: "dog"; fleas: 2, 0: number };
// type does not work because it does not exclude the key that is not a string
type test2 = OnlyStringKeys<MyAnimalsReloaded> // has 0: never as a key