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

Dynamic Super Types #11967

Open
tinganho opened this issue Oct 31, 2016 · 2 comments
Open

Dynamic Super Types #11967

tinganho opened this issue Oct 31, 2016 · 2 comments
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@tinganho
Copy link
Contributor

tinganho commented Oct 31, 2016

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
@HerringtonDarkholme
Copy link
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?

@tinganho
Copy link
Contributor Author

tinganho commented Nov 1, 2016

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.

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label May 24, 2017
@RyanCavanaugh RyanCavanaugh added Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript and removed Needs Investigation This issue needs a team member to investigate its status. labels Sep 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

3 participants