我正在试着让这个工作的JavaScript(但不是我的:P)通过类型检查。也许这只是在一天晚了,但我可以使用一些帮助。
class GPUTexture {}
class BaseState<T> {
webgpuObject: T | null;
constructor() {
this.webgpuObject = null;
}
}
class TextureState extends BaseState<GPUTexture> {}
interface CaptureStateBase<GPUType> {
webgpuObject: GPUType | null;
}
class ObjectRegistry<GPUType extends Object, CaptureState extends CaptureStateBase<GPUType>> {
iterating: boolean;
dataMap: WeakMap<GPUType, CaptureState>;
objects: WeakRef<GPUType>[];
constructor() {
this.dataMap = new WeakMap();
this.objects = [];
this.iterating = false;
}
add(obj: GPUType, data: CaptureState) {
if (this.iterating) {
throw new Error('Mutating Registry while iterating it.');
}
this.dataMap.set(obj, data);
this.objects.push(new WeakRef(obj));
data.webgpuObject = obj;
}
get(obj: GPUType) {
return this.dataMap.get(obj);
}
[Symbol.iterator](): IterableIterator<CaptureState> {
let i = 0;
this.iterating = true;
return {
registry: this,
next() {
while (i < this.registry.objects.length) {
const obj = this.registry.objects[i++].deref();
if (obj === undefined) {
continue;
}
return { value: this.registry.get(obj), done: false };
}
this.registry.iterating = false;
return { done: true };
},
};
}
}
const textures = new ObjectRegistry<GPUTexture, TextureState>();
我尝试简化代码,但我不确定我是否理解错误。我实际上看到了两个错误。一个是,typescript似乎混淆了next
中的this
。我抱怨this.registry
不存在
另一个是
(方法)迭代器〈捕获状态,任意,未定义〉. next(...参数:[]| [未定义]):迭代器结果〈捕获状态,任意〉
类型'()=〉{值:任何;完成:错误;}| {完成:真;值?:未定义; "}"不能赋给类型"(...参数:[]| [未定义])=〉迭代器结果〈捕获状态,任意〉'。
类型"{值:任何;完成:错误;}| {完成:真;值?:未定义; }"不能赋给类型" IteratorResult〈CaptureState,any〉"。
键入"{完成:真;值?:无法将"未定义;}"赋给类型"IteratorResult〈CaptureState,any〉"。
键入"{完成:真;值?:未定义;"}"不能赋给类型" IteratorReturnResult "。
属性"value"在类型"{done:真;值?:未定义;}",但在类型" IteratorReturnResult "中是必需的。(2322)
打字场
我试图通过像这样向上移动next
来修复第一个问题
class GPUTexture {}
class BaseState<T> {
webgpuObject: T | null;
constructor() {
this.webgpuObject = null;
}
}
class TextureState extends BaseState<GPUTexture> {}
interface CaptureStateBase<GPUType> {
webgpuObject: GPUType | null;
}
class ObjectRegistry<GPUType extends Object, CaptureState extends CaptureStateBase<GPUType>> {
iterating: boolean;
dataMap: WeakMap<GPUType, CaptureState>;
objects: WeakRef<GPUType>[];
constructor() {
this.dataMap = new WeakMap();
this.objects = [];
this.iterating = false;
}
add(obj: GPUType, data: CaptureState) {
if (this.iterating) {
throw new Error('Mutating Registry while iterating it.');
}
this.dataMap.set(obj, data);
this.objects.push(new WeakRef(obj));
data.webgpuObject = obj;
}
get(obj: GPUType) {
return this.dataMap.get(obj);
}
[Symbol.iterator](): IterableIterator<CaptureState> {
let i = 0;
this.iterating = true;
const next = () => {
while (i < this.objects.length) {
const obj = this.objects[i++].deref();
if (obj === undefined) {
continue;
}
return { value: this.get(obj), done: false };
}
this.iterating = false;
return { done: true };
};
return { next };
}
}
const textures = new ObjectRegistry<GPUTexture, TextureState>();
打字场
这解决了第一个错误,但没有解决第二个错误
1条答案
按热度按时间q3qa4bjr1#
在迭代器对象上引用一个单独的
this.registry
作为自定义值是很奇怪的,可能会导致问题。完全抛弃它,只使用一个arrow函数和外部的this
会更容易。这样,它的类型就可以 * 正常工作 *-你的arrow函数是正确的想法。在此之后,typing here只会再发出一个警告:
这可以通过指定
this
与示例化的类相同并让TypeScript自己推断迭代器类型来修复。Playground链接
该
属性"value"在类型"{done:真;值?:未定义;}",但在类型" IteratorReturnResult "中是必需的。(2322)
可以通过改变
到
但看起来没必要。