Skip to content

Slow types: Better detection/fallback for complex constant declarations #155

@bradenmacdonald

Description

@bradenmacdonald

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:
Screenshot 2024-03-03 at 2 13 43 PM

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
Screenshot 2024-03-03 at 2 21 41 PM Screenshot 2024-03-03 at 2 19 14 PM

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?

Metadata

Metadata

Assignees

Projects

Status

Ready

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions