Javascript 为什么打字稿显示“打印”字样;无法调用可能为';未定义';。ts(2722)“;可选链接运算符后出错?
在此逗留期间,我决定深入研究TypeScript,并开始通过实现一些基本数据结构来实践它。我试图实现一个使用自定义节点的自定义堆栈 我的堆栈节点定义如下:Javascript 为什么打字稿显示“打印”字样;无法调用可能为';未定义';。ts(2722)“;可选链接运算符后出错?,javascript,typescript,undefined,optional-chaining,Javascript,Typescript,Undefined,Optional Chaining,在此逗留期间,我决定深入研究TypeScript,并开始通过实现一些基本数据结构来实践它。我试图实现一个使用自定义节点的自定义堆栈 我的堆栈节点定义如下: 类堆栈节点{ 私人增值税:任何; 私有nxt:StackNode |未定义=未定义; 构造函数(val:any,nxt?:StackNode |未定义){ this.val=val; this.nxt=nxt | |未定义; } 获取值():任意{ 返回此.value; } get next():StackNode |未定义{ 把这个还给我,
类堆栈节点{
私人增值税:任何;
私有nxt:StackNode |未定义=未定义;
构造函数(val:any,nxt?:StackNode |未定义){
this.val=val;
this.nxt=nxt | |未定义;
}
获取值():任意{
返回此.value;
}
get next():StackNode |未定义{
把这个还给我,下一个;
}
}
导出默认堆栈节点;
和实际堆栈:
类堆栈{
私人容量!:数字;
私有顶部?:StackNode |未定义=未定义;
私有大小:数字=0;
构造函数(容量:数字,初始值?:数组){
这个。容量=容量;
if(初始值){
this.size=initialValues.length;
this.top=this.\u initStack(initialValues,initialValues.length-1);
}
};
private\u initStack=(数组:array,idx:number):StackNode=>{
如果(idx==0){
返回新的StackNode(数组[idx],未定义);
}否则{
返回新的StackNode(数组[idx],this.\u initStack(数组,idx-1));
}
}
pop():任何{
常量值=此.top?.value();
this.top=this.top?.next();
返回值;
}
}
导出默认堆栈;
这里的问题是pop方法中带有可选链接运算符的行this.top=this.top?.next()
我所理解的是表达式this.top?.next()
应该与
(this.top==null | | this.top==undefined)?未定义:this.top.next()
但我还是得到了错误
无法调用可能为“未定义”的对象。ts(2722)
当呼叫发出时,即使在该阶段不应再未定义
为什么?我错过了什么?StackNode.nxt和Stack.top都允许未定义。我试着用老办法这样做:
if(this.top!==null | | this.top!==未定义){
常量值=this.top.value()
this.top=this.top.next()
}
但是我仍然得到了相同的错误,即使这里应该确保this.top
不能是未定义的,但必须是,或者至少应该是StackNode类型
这应该是如何工作的,当从空堆栈弹出时,pop方法将返回undefined,当弹出最后一个元素时,它的下一个元素,即undefined,被设置为堆栈的顶部
我使用的是TS 3.8.3您将next定义为一个getter,因此必须像这样访问它:
this.top=this.top?.next
const value=this.top?.value()的唯一原因代码>甚至编译都是因为您使用了“any”(永远不要这样做!!),typescript假设get value
可能会返回您正在调用的函数
您应该使用泛型定义StackNode。比如说,
class StackNode<T> {
private val: T;
private nxt: StackNode<T> | undefined = undefined;
constructor(val: T, nxt?: StackNode<T> | undefined) {
this.val = val;
this.nxt = nxt || undefined;
}
get value(): T {
return this.value;
}
get next(): StackNode<T> {
return this.next;
}
}
class Stack<T> {
private capacity!: number;
private top?: StackNode<T> | undefined = undefined;
private size: number = 0;
constructor(capacity: number, initialValues?: Array<any>) {
this.capacity = capacity;
if (initialValues) {
this.size = initialValues.length;
this.top = this._initStack(initialValues, initialValues.length - 1);
}
};
private _initStack = (array: Array<any>, idx: number): StackNode<T> => {
if (idx == 0) {
return new StackNode(array[idx], undefined);
} else {
return new StackNode(array[idx], this._initStack(array, idx-1));
}
}
pop(): T | undefined {
const value = this.top?.value(); //doesn't compile
this.top = this.top?.next(); //doesn't compile either
return value;
}
}
类堆栈节点{
私有val:T;
私有nxt:StackNode |未定义=未定义;
构造函数(val:T,nxt?:StackNode |未定义){
this.val=val;
this.nxt=nxt | |未定义;
}
获取值():T{
返回此.value;
}
get next():StackNode{
把这个还给我,下一个;
}
}
类堆栈{
私人容量!:数字;
私有顶部?:StackNode |未定义=未定义;
私有大小:数字=0;
构造函数(容量:数字,初始值?:数组){
这个。容量=容量;
if(初始值){
this.size=initialValues.length;
this.top=this.\u initStack(initialValues,initialValues.length-1);
}
};
private\u initStack=(数组:array,idx:number):StackNode=>{
如果(idx==0){
返回新的StackNode(数组[idx],未定义);
}否则{
返回新的StackNode(数组[idx],this.\u initStack(数组,idx-1));
}
}
pop():T |未定义{
const value=this.top?.value();//不编译
this.top=this.top?.next();//也不编译
返回值;
}
}
然后,const value=this.top?.value()
也不会编译。在您学习typescript时,我已经编辑了我的答案,以包含一个泛型示例来解决此问题。祝你一切顺利!哦,好吧,这是我完全错过的!思想获取者和其他方法一样可以访问。至于“any”,很可能有更好的方法,但目前我不知道它是什么。@zaplec重新加载你的页面,我用更好的方法编辑:)当我发布时,你已经用细节编辑了你的答案:D非常感谢!我也会检查泛型。非常感谢您的回答!