I want to write a base interface which has self referential children and I want to extend that interface so that children become the type of new interface.
Example of solution I tried using generics:
interface ICommentBase<T> {
author: string;
children: T[];
}
interface IComment<T> extends ICommentBase<T> {
upvotes: number;
}
interface ICommentSuper<T> extends IComment<T> {
reported: boolean;
}
// error because IComment needs a type argument etc.
function readChildrenUpvotes(comment: IComment<IComment>) {
// do something
}
I can fix this only in last extend without using type arguments:
// now no error will show when using this interface
interface ICommentSuperTwo extends IComment<ICommentSuperTwo> {
reported: boolean;
}
But this interface can no longer be extended with new properties being part of children.
// children[0].creationDate will throw error because creationDate
// does not exist on interface ICommentSuperTwo
interface ICommentSuperDuper extends ICommentSuperTwo {
creationDate: string;
}
Is there a solution I am missing?
Another explanation:
I want to operate on interface:
const baseComments = {
author: "anon",
children: [
{
author: "anon",
children: [],
},
],
};
Then I want to extend above interface and operate on this.
const comments = {
author: "anon",
upvotes: 0,
children: [
{
author: "anon",
upvotes: 0,
children: [],
},
],
};
Then I want to extend above interface and operate on this.
const improvedComments = {
author: "anon",
upvotes: 0,
reported: false,
children: [
{
author: "anon",
upvotes: 0,
reported: false,
children: [],
},
],
};
If you want children
to be of the same type as the current interface, the simplest solution is probably to use polymorphic this
:
interface ICommentBase {
author: string;
children: this[];
}
interface IComment extends ICommentBase {
upvotes: number;
}
interface ICommentSuper extends IComment {
reported: boolean;
}
function readChildrenUpvotes(comment: IComment) {
// do something
}
const baseComments: ICommentBase = {
author: "anon",
children: [
{
author: "anon",
children: [],
},
],
};
const comments: IComment = {
author: "anon",
upvotes: 0,
children: [
{
author: "anon",
upvotes: 0,
children: [],
},
],
};
const improvedComments: ICommentSuper = {
author: "anon",
upvotes: 0,
reported: false,
children: [
{
author: "anon",
upvotes: 0,
reported: false,
children: [],
},
],
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.