具有映射类型的代理
Proxy with mapped types
我遍历了 TS Handbook,然后我来到了映射类型。有一个代码片段可以将对象 属性 包装到代理中。
type Proxy<T> = {
get(): T;
set(value: T): void;
}
type Proxify<T> = {
[P in keyof T]: Proxy<T[P]>;
}
function proxify<T>(o: T): Proxify<T> {
// ... wrap proxies ...
}
let proxyProps = proxify(props);
我试图用我的实现来填补 proxify 函数中的空白,我得到了这样的结果:
function proxify<T>(t: T): Proxify<T> {
let result = <Proxify<T>>{};
for (const k in t) {
result[k] = { //(*) from that moment I lose strong typing
get: () => t[k],
set: (value) => t[k] = value
}
}
return result;
}
我无法控制循环内的类型,所有内容都必须由 any 类型输入。假设我的实施完全正确,如何应对?
执行似乎没问题。创建对象时会失去一些安全性,但您不会失去所有安全性。您仍然获得的打字量实际上可能会让您感到惊讶
function proxify<T>(t: T): Proxify<T> {
let result = <Proxify<T>>{};
for (const k in t) { // k is of type Extract<keyof T, string> so it must be a key of T
// result[k] and t[k] both work because k is a key of both T and Proxify<T> but result['random'] would be invalid
result[k] = { // get/set fields are checked, so _get would be an error
// the return of get must be T[Extract<keyof T, string>] so ()=> 0 would be an error
get: () => t[k],
// value and t[k] must be T[Extract<keyof T, string>] so t[k] = '' would also be an error
set: (value) => t[k] = value
}
}
return result;
}
我的实现版本如下。我找不到在 get 和 set 中强制类型安全的方法。如果有某种方法可以编写像这样的属性,它可能会更优雅 get():PropType , set(value:PropType)
function proxify<T>(o: T): Proxify<T> {
const proxifyObj: Proxify<T> = <Proxify<T>>{};
Object.keys(o).map((key) => {
proxifyObj[key] = {
get() {
return o[key];
},
set(value) {
o[key] = value;
}
};
});
return proxifyObj;
}
我遍历了 TS Handbook,然后我来到了映射类型。有一个代码片段可以将对象 属性 包装到代理中。
type Proxy<T> = {
get(): T;
set(value: T): void;
}
type Proxify<T> = {
[P in keyof T]: Proxy<T[P]>;
}
function proxify<T>(o: T): Proxify<T> {
// ... wrap proxies ...
}
let proxyProps = proxify(props);
我试图用我的实现来填补 proxify 函数中的空白,我得到了这样的结果:
function proxify<T>(t: T): Proxify<T> {
let result = <Proxify<T>>{};
for (const k in t) {
result[k] = { //(*) from that moment I lose strong typing
get: () => t[k],
set: (value) => t[k] = value
}
}
return result;
}
我无法控制循环内的类型,所有内容都必须由 any 类型输入。假设我的实施完全正确,如何应对?
执行似乎没问题。创建对象时会失去一些安全性,但您不会失去所有安全性。您仍然获得的打字量实际上可能会让您感到惊讶
function proxify<T>(t: T): Proxify<T> {
let result = <Proxify<T>>{};
for (const k in t) { // k is of type Extract<keyof T, string> so it must be a key of T
// result[k] and t[k] both work because k is a key of both T and Proxify<T> but result['random'] would be invalid
result[k] = { // get/set fields are checked, so _get would be an error
// the return of get must be T[Extract<keyof T, string>] so ()=> 0 would be an error
get: () => t[k],
// value and t[k] must be T[Extract<keyof T, string>] so t[k] = '' would also be an error
set: (value) => t[k] = value
}
}
return result;
}
我的实现版本如下。我找不到在 get 和 set 中强制类型安全的方法。如果有某种方法可以编写像这样的属性,它可能会更优雅 get():PropType , set(value:PropType)
function proxify<T>(o: T): Proxify<T> {
const proxifyObj: Proxify<T> = <Proxify<T>>{};
Object.keys(o).map((key) => {
proxifyObj[key] = {
get() {
return o[key];
},
set(value) {
o[key] = value;
}
};
});
return proxifyObj;
}