gpt4 book ai didi

typescript - 有没有办法在 typescript 中委托(delegate)索引属性?

转载 作者:搜寻专家 更新时间:2023-10-30 20:34:52 26 4
gpt4 key购买 nike

有什么方法可以将索引属性委托(delegate)给 typescript 中的成员吗?我正在编写一个包装器,我想将索引属性委托(delegate)给我正在包装的对象。

类似于:

interface MyStringArray {
length : number;
clear() : void;
[index: number] : string;
}

export class MyStringArrayWrapper implements MyStringArray {

private wrapped : MyStringArray;

public get length() : number {
return this.wrapped.length;
}

public clear() : void {
this.wrapped.clear();
}

// This doesn't work
public get [index : number] : string {
return this.wrapped[index];
}

// This doesn't work either
public set [index : number](value: string) {
this.wrapped[index] = value;
}
}

最佳答案

TypeScript 不允许这样做,因为它无法为这样的构造生成 JavaScript 代码。在 JavaScript 中无法在设置任何属性时调用的类上定义一个包罗万象的 getter/setter。

我能得到的最接近的方法是在类上定义hasItemgetItemsetItem 方法,然后包装每个实例 类在 ES2015 Proxy 对象中的原型(prototype),该对象代理所有 getset s 到该实例的属性。

function isArrayIndex(key) {
var keyAsNumber = +key; // convert string to number
if (keyAsNumber < 0) {
return false; // must be positive or zero
}
if (keyAsNumber !== keyAsNumber|0) {
return false; // must be integer
}
return true;
}

function toArrayIndex(key) {
return key|0; // convert string to integer
}

function MyArrayWrapper(wrapped) {
this.wrapped = wrapped;
}

MyArrayWrapper.prototype = {
get length() {
return this.wrapped.length;
},

clear() {
this.wrapped.length = 0;
},

getItem(index) {
return this.wrapped[index];
},

setItem(index, value) {
this.wrapped[index] = value;
}

}

var MyArrayWrapperProxyHandler = {
get: function (target, key, receiver) {
if (isArrayIndex(key)) {
return receiver.getItem(toArrayIndex(key));
} else {
return Reflect.get(target, key, receiver);
}
},
set: function (target, key, value, receiver) {
if (isArrayIndex(key)) {
return receiver.setItem(toArrayIndex(key), value);
} else {
return Reflect.set(target, key, value, receiver);
}
}
};

MyArrayWrapper.prototype = new Proxy(MyArrayWrapper.prototype, MyArrayWrapperProxyHandler);

var array = ['a', 'b', 'c'];
var wrapper = new MyArrayWrapper(array);

console.log('read:', wrapper[2] === 'c'); // true, reads from wrapped array

wrapper[3] = 'd';
console.log('write:', array[3] === 'd'); // true, writes to wrapped array
console.log('resize:', wrapper.length === 4); // true, wrapped array is resized

这需要支持 Proxy 对象的现代浏览器,并且它使用 Reflect 通过原型(prototype)链手动传递其他属性(例如 this.wrapped)。有很多东西不起作用(例如 '2' in wrappedfalse),因为我没有找到正确捕获它们的方法。

此外,代理比直接使用 hasItem/getItem/setItem 慢得多,因此我不建议将它们用于任何对性能至关重要的事情。它们的使用也可能非常困惑,因为当涉及代理时,一个简单的 foo[0] = 'bar' 突然可以做各种疯狂的事情。

如果您对以上所有内容都满意,那么当然可以,将一些类型添加到上面的代码片段中,您将拥有带有委托(delegate)数组索引 getter/setter 的 TypeScript 代码。这实际上更像是一个“概念证明”,我只是想看看你能把 JavaScript 推到什么程度。 :-P

关于typescript - 有没有办法在 typescript 中委托(delegate)索引属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38925391/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com