Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type inference performance issue #60772

Closed
1 task done
gumartinezedicom opened this issue Dec 16, 2024 · 1 comment
Closed
1 task done

Type inference performance issue #60772

gumartinezedicom opened this issue Dec 16, 2024 · 1 comment
Labels
Question An issue which isn't directly actionable in code

Comments

@gumartinezedicom
Copy link

Acknowledgement

  • I acknowledge that issues using this template may be closed without further explanation at the maintainer's discretion.

Comment

I have been trying to use type inference for a specific case.

interface Model {
    field1: Date;
    field2: number;
}

interface Column<T, K extends keyof T = keyof T> {
    field: K;
    transformation?: (value: T[K], data: Model) => string;
}

const columns: Column<Model>[] =  [
    {
        field: 'field1',
        transformation: (value) => value.getTime()
    }
];

In 'transformation,' I would like 'value' to be of type Date instead of being number | Date.

To achieve this, I created two helper types to get the union of possible 'field' types and to correctly infer the type from 'field' in the callback.

interface Column<
    T,
    K extends NestedKeyOf<T>,
    V extends NestedValueOf<T, K>,
> {
    field: K & string;
    transformation?: (value: V, data: Model) => string;
}

for NestedKeyOf

type NestedKeyOf<Type> = Type extends string | number
  ? never
  : {
      [Key in TraversableKeys<Type>]: NestedSingleKeyOf<Type, Key>;
    }[TraversableKeys<Type>];

type TraversableKeys<Type> = Exclude<keyof Type & (string | number), 'prototype'>;

type NestedSingleKeyOf<Type, Key extends keyof Type> = Key extends string
  ? IsArray<
      Type[Key],
      Key | `${Key}.${number}`,
      IsComplexObject<Type[Key], Key | `${Key}.${NestedKeyOf<Type[Key]>}`, Key>
    >
  : never;

type IsArray<O, T, F> = O extends Array<unknown> ? T : F;

type IsComplexObject<O, T, F> = O extends Date | Array<unknown> | Blob
  ? F
  : IsObject<O, T, F>;

type IsObject<O, T, F> = O extends object ? T : F;

for NestedValueOf

type NestedValueOf<Type, Key extends string> = Key extends `${infer Head}.${infer Tail}`
  ? Head extends keyof Type
    ? IsNumberFromString<
        Tail,
        IsArrayValue<Type[Head], NestedValueOf<Type[Head], Tail>>,
        NestedValueOf<Type[Head], Tail>
      >
    : never
  : IsKeyOfType<Type, Key>;

type IsArrayValue<O, F> = O extends Array<infer U> ? U : F;

type IsNumberFromString<O, T, F> = O extends `${number}` ? T : F;

type IsKeyOfType<Type, Key> = Key extends keyof Type ? Type[Key] : never;

This way, the type of 'value' is correctly inferred in the callback. I can even access different levels of nesting using dots, such as 'field1.field1-2.field1-2-1,' or even array positions, inferring the correct type like 'field1.6'.

From this point, my problem is that in cases with multiple levels of nesting (3 or more) and types with many properties (20–30 or more), it takes a long time to compute the corresponding type. Is there any way to optimize the typing or handle it differently?

@RyanCavanaugh RyanCavanaugh added the Question An issue which isn't directly actionable in code label Dec 16, 2024
@typescript-bot
Copy link
Collaborator

This issue has been marked as "Question" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@typescript-bot typescript-bot closed this as not planned Won't fix, can't repro, duplicate, stale Dec 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

3 participants