-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Mapped instanceof class type #13009
Comments
The problem is that this gets messy if you have multiple construct signatures, or a possibly different Though all in all, I want this for grabbing the return type of a function types in general (types with call or construct signatures). #6606 is vaguely related. |
I think your requirement can be filled with the following implementation. type Constructor<T> = {
[P in keyof T]: { new (...args: any[]): T[P]; };
}
interface Configurations<R> {
relations: Constructor<R>;
}
class Model<P, R>{
static define<P, R>(configurations?: Configurations<R>) {
return class extends Model<P, R> {
}
}
props: P & R;
/**
* Get property value.
*/
public get<K extends keyof P>(prop: K): P[K] | null;
public get<K extends keyof R>(prop: K): R[K] | null;
public get(prop: any): any {
return typeof this.props[prop] !== 'undefined' ? this.props[prop] : null;
}
}
interface IUser {
name: string;
}
const User = Model.define<IUser, {}>();
interface IPost {
name: string;
}
const relations = {
owner: User,
};
const Post = Model.define<IPost, { owner: Model<IUser, {}> }>({
relations: relations,
});
const post = new Post();
post.get('name');
const p = post.get('owner'); // User, and not typeof User |
@kimamula your solution doesn't solve the problem. You still declare const relations = {
owner: User,
};
const Post = Model.define<IPost, { owner: Model<IUser, {}> }>({
relations: relations,
}); |
@tinganho you can also write as follows in my example. const Post = Model.define<IPost, { owner: Model<IUser, {}> }>({
relations: {
owner: User,
},
}); Or I might be misunderstanding your problem. |
You mean something like |
Well, though it is not possible to grab the return types of functions, I suppose something like the following would work in most of the cases, as I wrote above. type Functions<FunctionReturnTypes> = {
[P in keyof FunctionReturnTypes]: () => FunctionReturnTypes[P]
} |
@kimamula these are suggestions on solutions to problems that are supposably not solvable today. |
Why can not you just write your generic types to capture the instance; instead of capturing the class, and then needing to get the instance out of it.. e.g.: type Class<T> = {
new (...args: any[]): T;
};
type Map<T> = {
[x: string]: T;
}
type Relations<T> = Map<Class<T>>;
interface Configurations<T> {
relations: Relations<T>;
}
class Model<T>{
static define<T>(configurations?: Configurations<Model<T>>) {
return class extends Model<T> {
}
}
props: T;
/**
* Get property value.
*/
public get<K extends keyof (T)>(prop: K): (T)[K] | null {
return typeof this.props[prop] !== 'undefined' ? this.props[prop] : null;
}
}
interface IUser {
name: string;
}
const User = Model.define<IUser>();
interface IPost {
name: string;
}
const relations = {
owner: User,
};
const Post = Model.define({
relations: relations,
});
const post = new Post();
post.get('name'); // this works now
const p = post.get('owner'); // this does not |
@mhegazy I think you probably misunderstood my case. const relations = {
owner1: User,
comment: Comment,
}; Your example does not seem to reflect that? Since And I want const p = post.get('owner'); // User But remember, I don't want declare There are a few MVC libs that does something similar with relational mapping. Though, none achieve this with static types. |
I really cannot understand why you think |
The essential problem here may be that TypeScript requires all type parameters if it cannot infer any of them. const Post = Model.define<IPost, >({ // inferable type parameter can be omitted
relations: {
owner: User,
},
}); I actually sometimes feel I need this feature. EDIT: There is already an issue for this feature. |
if const relations = {
owner1: User,
comment: Comment,
}; What is is I would say you want |
Why does |
Some API in pure JS accepts classes declarations as input and generate instances of that class as output.
As of know, to my knowledge, there is no way to map that, if the input argument accepts an index signature of class declarations, such as below:
It would be great if I could map from class type to instance type in those cases.
Where the
instanceof
operator just get the instance side of a class. So the below is equivalent:This is my real use case, a project I'm working on where I try to design some data classes. Where I do relational mapping for model objects:
One alternative right now, is to pass in the type manually, which is quite tedious:
The text was updated successfully, but these errors were encountered: