six*_*rm1 8 javascript typescript
我想强输入属性名称
myMethod(model => model.userId);
public myMethod(model: () => any) {
//Must print "userId"
}
Run Code Online (Sandbox Code Playgroud)
我已经知道这行不通,因为 JavaScript 会评估 userId。
在 C# 中很容易做到:
是否可以在 TypeScript/JavaScript 中做到这一点?
与 C# 不同,可以在 JavaScript 中通过名称动态访问属性(因此也可以在 Typescript 中),因此您可以将名称作为字符串传递给函数并使用括号表示法访问属性:
myMethod(model, "userId")
Run Code Online (Sandbox Code Playgroud)
现在关于打字稿很酷的事情是这个字符串实际上可以是类型安全的:
function myMethod<T, K extends keyof T>(model: T, key: K) {
const value = model[key];
//...
}
Run Code Online (Sandbox Code Playgroud)
如果您真的想像在 C# 中那样做类似的事情(不要!!),请执行以下操作:
function myMethod(model: () => any) {
const key = model.toString().split(".")[1];
//...
}
Run Code Online (Sandbox Code Playgroud)
如果我明白你在问什么,你想检查一个属性检索箭头函数,并返回它返回的属性的名称?对于像 JavaScript 这样的弱/动态类型语言来说,这听起来是个坏主意,任何一个理智的人都应该尖叫着逃跑。尽管如此,假设我要么疯了要么被强迫,下面是我将如何在编译为 ES2015 的 TypeScript 2.9 中尝试这样做:
type ValueOf<T> = T[keyof T];
function evilMagic<T, V extends T[keyof T]>(
f: (x: T)=>V
): ValueOf<{[K in keyof T]: T[K] extends V ? K : never}>;
function evilMagic(f:(x: any)=>any): keyof any {
var p = new Proxy({}, {
get(target, prop) { return prop }
})
return f(p);
}
Run Code Online (Sandbox Code Playgroud)
该函数evilMagic接受一个属性获取函数并尝试返回它返回的属性的名称。输出的类型很难解释,但基本上它是属性获取函数期望的参数keyof Twhere 的某个子集T。该函数的实现使用了一个Proxy对象p,该对象的作用类似于某个对象,其值始终与其键相同。即,p.foo是"foo",并且p.bar是"bar",并且p[10]是"10"。打电话给财产获取者p,abracadabra,你有财产的名字。
下面是它的使用示例:
interface Person {
name: string;
age: number;
numberOfLimbs: number;
}
const m = evilMagic((x: Person) => x.age); // typed as "age"|"numberOfLimbs";
console.log(m); // "age"
Run Code Online (Sandbox Code Playgroud)
在编译时,TypeScript 只能判断它m是"age"or 之一"numberOfLimbs",因为它只看到回调函数返回一个number。在运行时,您会得到"age"预期的结果。
然而,这整件事让我感到害怕,我觉得写它不干净;当传递给该代理时,期望某种类型值的函数可能会做各种疯狂的事情。我不愿意想到这样的代码最终会出现在任何用于生产的东西中,尽管它可能是一个有用的调试工具。请告诉我您只会将它用作调试工具!
无论如何,希望有帮助。祝你好运!
| 归档时间: |
|
| 查看次数: |
2395 次 |
| 最近记录: |