Skip to content

New syntax for advanced typing array of arguments #33778

Closed
@sviat9440

Description

@sviat9440

Search Terms

new syntax, advanced types, generic, array of arguments

Suggestion

Hi, everybody!
I think it would be cool to create a solution to this problem.

If you want to control the typing of the result of a function based on an unlimited number of incoming arguments, you will need a huge number of overloads.

Use Cases

For example, you have a class that contains a property configuration:

class PropertyConstructor<T> {
  type: T;
}

class PropertyConfiguration<T, S extends keyof any> {
   constructor(
      public propertyKey: S,
      public propertyConstructor: new () => PropertyConstructor<T>,
   ) {}
}

Next, create several inheritors of constructors:

class StringPropertyConstructor extends PropertyConstructor<string> {
}

class NumberPropertyConstructor extends PropertyConstructor<number> {
}

Next, create function, that will build class with property configs:

type Join<T, S extends keyof any> = {[P in S]: T};

function CreateClass<T1, S1 extends keyof any>(p1: PropertyConfiguration<T1, S1>): new () => Join<T1, S1>;
function CreateClass<T1, S1 extends keyof any, T2, S2 extends keyof any>(
  p1: PropertyConfiguration<T1, S1>,
  p2: PropertyConfiguration<T2, S2>,
): new () => Join<T1, S1> & Join<T2, S2>;
// ... And so on. It's very uncomfortable and ugly.
function CreateClass(...properties: Array<PropertyConfiguration<any, keyof any>>): new () => any {
  class NewClass {}
  // Here was the logic of executing property constructors
  return NewClass;
}

And create some instances of PropertyConfiguration:

const property1 = new PropertyConfiguration('property1', StringPropertyConstructor);
const property2 = new PropertyConfiguration('property2', NumberPropertyConstructor);

Funnaly, Let's try to apply it:

class A extends CreateClass(property1, property2) {
}

const a = new A();
a.property1 // string;
a.property2 // number;

It's works! But, very uncomfortable and ugly. For example if you want to create class with ten properties, you need to implement corresponded overloads.

Examples

As I see the solution to this problem:

type Join<T, S extends keyof any> = {[P in S]: T};

type Union<T extends Array<any>> = ... 
/*
built-in type for compare array types.
Example:
Union<[string, number]> => string & number
Union<[Join<string, 'property1'>, Join<number, 'property2'>]> => Join<string, 'property1'> & Join<number, 'property2'>
*/

function CreateClass<N extends number, T{N}, S{N} extends keyof any>(
  ...properties: [PropertyConfiguration<T{N}, S{N}>]
): new () => Union<[Join<T{N}, S{N}]> {
  class NewClass {}
  // Here was the logic of executing property constructors
  return NewClass;
}

Checklist

My suggestion meets these guidelines:

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions