typescript - 如何扩展用于类型检查的递归打字稿接口?
问题描述
我想编写一个具有自引用子级的基本接口,并且我想扩展该接口,以便子级成为新接口的类型。
我尝试使用泛型的解决方案示例:
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
}
我只能在最后一个扩展中解决这个问题,而不使用类型参数:
// now no error will show when using this interface
interface ICommentSuperTwo extends IComment<ICommentSuperTwo> {
reported: boolean;
}
但是这个接口不能再通过新属性作为子元素的一部分进行扩展。
// children[0].creationDate will throw error because creationDate
// does not exist on interface ICommentSuperTwo
interface ICommentSuperDuper extends ICommentSuperTwo {
creationDate: string;
}
有我缺少的解决方案吗?
另一种解释:
我想在界面上操作:
const baseComments = {
author: "anon",
children: [
{
author: "anon",
children: [],
},
],
};
然后我想扩展上面的接口并对此进行操作。
const comments = {
author: "anon",
upvotes: 0,
children: [
{
author: "anon",
upvotes: 0,
children: [],
},
],
};
然后我想扩展上面的接口并对此进行操作。
const improvedComments = {
author: "anon",
upvotes: 0,
reported: false,
children: [
{
author: "anon",
upvotes: 0,
reported: false,
children: [],
},
],
};
解决方案
如果您想children
与当前接口的类型相同,最简单的解决方案可能是使用 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: [],
},
],
};
推荐阅读
- sql - 如果表不存在,如何选择不出错
- arrays - 在矩阵数组中的每个矩阵上应用一个函数(MATLAB)
- qt - QML ListView:如何将所选项目复制到剪贴板?
- latex - 在 gnuplot 中使用 LaTex 字体时字母相互重叠
- python - 将事件添加到正在运行的 sched.scheduler
- c# - 使用 GCHandle.Alloc() 访问和操作固定内存的正确方法是什么?
- scikit-learn - 将决策树设为弱学习器,但得分 > 80%
- java - firebase.auth.FirebaseUser.linkWithCredential 抛出空指针异常
- javascript - 读取本地 JSON 文件并将其中每个对象的确定键返回到数组中
- java - 检查方法的返回是否为 List
有反射