Description
I often use a pattern in my code where some object has a lot of keys, and I want TypeScript to automatically detect the keys and make them part of the type.
For example, in quantity-math-js
:
/** SI prefixes */
export const prefixes = Object.freeze(
{
...
k: 1e+3, // kilo
M: 1e+6, // Mega
G: 1e+9, // Giga
..
} as const satisfies Record<string, number>,
);
I want for example to use that to define a related type using all the keys:
Here are two other examples of this pattern with even longer type definitions (more keys):
A second example: units.ts | A third example: Icon.tsx |
---|---|
![]() |
![]() |
Now, not surprisingly, deno lint
and deno publish
complain that these are "slow types". But given how complex the types are (see examples), I don't want to duplicate them in the code. And given how useful it is to have the keys available in my IDE with auto-completion, I don't want to simplify the types either.
I think a nice compromise solution would be to degrade these types to whatever type is specified using the satisfies
operator, when necessary. So if I slightly re-write my declaration as follows:
export const prefixes = Object.freeze(
{
...
k: 1e+3, // kilo
M: 1e+6, // Mega
G: 1e+9, // Giga
..
} as const,
) satisfies Record<string, number>;
Then ideally, deno
and typescript
and other first-class users of the code will have the full, detailed type with all the exact keys available, but for JSR's purposes of documenting this and transpiling it for Node.js or whatever other things need to avoid slow types, it should just simplify the type of this to Record<string, number>
which is OK to do because of the explicitsatisfies
declaration
Would that be possible?