Skip to content

Dynamic Super Types #11967

Description

@tinganho

Now, that #11929 is PR landed. I would really love to have some syntax to specify an arbitrary super type of T. This can be especially helpful in creating strongly typed ORM database frameworks.

Proposal

If K is constrained to be a key of T i.e K extends keyof T. Then the syntax:

{ ...K: ...T[K] }

Means spread the keys K and values of T in {}.

Example

Here is an example usage of an envisioned ORM framework:

interface IUser {
    id: string;
    name: string;
    email: string;
    createdAt: string;
    updatedAt: string;
    password: string;
    // ...
}

interface Options<T, K extends keyof T> {
     attributes: T[K][];
}

interface Model<IInstance> {
     findOne<K extends keyof IInstance>(options: Options<IInstance, K>): { ...K: ...IInstance[K] };
}

declare namespace DbContext {
   define<T>(): Model<T>;
}

const Users = DbContext.define<IUser>({
   id: { type: DbContext.STRING(50), allowNull: false },
   // ...
});

const user = Users.findOne({
    attributes: ['id', 'email', 'name'],
    where: {
        id: 1,
    }
});

user.id // no error
user.email // no error
user.name // no error

user.password // error 
user.createdAt // error
user.updatedAt // error

Activity

  1. HerringtonDarkholme commented on Nov 1, 2016

    @HerringtonDarkholme
    Contributor

    I wonder whether it is doable after #11929 landed. We can use overload + tuple syntax to mock it.

    Something like

    interface Model<IInstance> {
         findOne<K extends keyof IInstance>(options: [K]): { K: IInstance[K] };
         findOne<K extends keyof IInstance, K1 extends keyof IInstance>(options: [K, K1]): { K: IInstance[K] } & {K1: IInstance[K1]};
       // .... and more
    }

    If we have variadic kinds in #5453, maybe dynamic super type can be supported directly?

    Also, K extends keyof T seems to stand for one single string literal type to me. But in the return type it is used as a variadic kinds. May be ...K extends keyof T is better?

  2. tinganho commented on Nov 1, 2016

    @tinganho
    ContributorAuthor

    Also, K extends keyof T seems to stand for one single string literal type to me. But in the return type it is used as a variadic kinds. May be ...K extends keyof T is better?

    I stumbled upon this too. Though this problem might be a bit hard to solve perfectly.

  3. added
    Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this feature
    SuggestionAn idea for TypeScript
    and removed
    Needs InvestigationThis issue needs a team member to investigate its status.
    on Sep 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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