I want to create a type based on the keys of another object in TypeScript.
I have managed to do this with type inference. But if I use an explicit type Record<string, something>
then keyof
gives me string
instead of a union of the actual keys I used.
Here's example code:
type FileType = "image" | "video" | "document";
type FileTypeList = Record<string, FileType>
const inferedFileList = {
a: "image",
b: "video",
c: "document"
}
//type files = "a" | "b" | "c"
type files = keyof typeof inferedFileList;
const explicitelyTypedList : FileTypeList = {
a: "image",
b: "video",
c: "document"
}
//type typedFiles = string
type typedFiles = keyof typeof explicitelyTypedList;
Relevant TypeScript Playground
Is there any way I can use explicit typing in the form Record<string, something>
and still get a union type with keyof
? I imagine it would be possible with a keyword that behaves like typeof
but uses the shape of an object instead of its declared type, but does TypeScript implement such a thing ?
Type inference can be really powerful in TypeScript and there is nothing wrong with not annotating types yourself.
When you explicitly type the object, you effectively type it less precisely:
Maybe you need this type later in the process, so you can do something like:
so get the whole Record type with just existing keys (a, b, c)
If you want to guard that object have valid values but also staticly known keys, you can try this approach: