Typescript: [performance] lazy types

Created on 1 Oct 2020  路  3Comments  路  Source: microsoft/TypeScript

Search Terms


type performance. computed types. lazy types

Suggestion

The ability to mark a type as lazily computed.

Lazily computed means the type is fully ignored if it's not referenced from anywhere else in the code base.

Use Cases

For gqless we have a complex TypeData<schema.TypeName> type, which takes a GraphQL schema type and transforms it into a data type.

Doing this is relatively cheap for a single type. But for some APIs (GitHub for example) there can be thousands of different types. Including 1000 unreferenced calls to the TypeData type vastly slows down the entire editor, even when editing non-related source files.

These types are guaranteed to be correct, so there's no need to run the type checker on them if they're not referenced anywhere.

Without the ability to mark types as 'lazy', the only other options are to either create thousands of files with the types in them - or resort to some background process which manually comments out types when not in use.

Examples

// @ts-lazy
type MyType = ComputeIntensiveType<1, 2>

// if MyType resulted in a type error, the build would still pass
// because MyType wasn't actually used anywhere

Checklist

My suggestion meets these guidelines:

  • [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • [x] This wouldn't change the runtime behavior of existing JavaScript code
  • [x] This could be implemented without emitting different JS based on the types of the expressions
  • [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • [x] This feature would agree with the rest of TypeScript's Design Goals.

Most helpful comment

This is already the behavior for every type in a .d.ts file when --skipLibCheck is enabled. That seems like it's your use case already?

All 3 comments

If this would result in improved performance, then shouldn't all types be lazy? Similarly to how modules aren't loaded if they aren't referenced?

when running TSC it doesn't do it lazily, when doing intellisense stuff it is super lazy. I would actually disagree with this because sometimes I use unused type declarations for validations, for example:

export enum Actions {
    A = "A",
    B = "B",
}
// this throws a compile error on `= Actions` if there is a enum value that isn't equal to it's key.
type EnsureEnumKeysAreEqualToValues<Keys extends keyof typeof Actions = Actions> = unknown;

Since the code base this is in relies on the enum names being equal to the keys this EnsureEnumKeysAreEqualToValues is added to the end to ensure this instead of confusing errors being thrown elsewhere in the code base that relies that Actions is assignable to keyof typeof Actions. If this was just never evaluated because it was unused then we'd just get those misleading errors elsewhere in the code base which is undesirable.

This is already the behavior for every type in a .d.ts file when --skipLibCheck is enabled. That seems like it's your use case already?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

weswigham picture weswigham  路  3Comments

dlaberge picture dlaberge  路  3Comments

Roam-Cooper picture Roam-Cooper  路  3Comments

kyasbal-1994 picture kyasbal-1994  路  3Comments

siddjain picture siddjain  路  3Comments