在C#中,可以通过字符串值获取对象属性的名称。
nameof(object.myProperty)->“ myProprty”
可以用Javascript / Typescript完成吗?
Object.Keys()是我发现的唯一东西,但是它给了我所有的键。
示例我要实现的目标:
export interface myObject {
myProperty: string;
}
console.log(myObject["myProperty"]);
假设我出于某些原因将界面更改为:
export interface myObject {
myPropertyOther: string;
}
console.log(myObject["myProperty"]); // This will not give an error on build
所以我想要这样的东西:
console.log(myObject[nameOf(myObject.myProperty)]
// This will give an error on build when the interface is changed
答案 0 :(得分:1)
Javascript / Typescript中没有nameof
运算符。您可以创建一个使用另一个对象的键的函数,并由打字稿编译器进行检查:
function keyOf<T>(o: T, k: keyof T) {
return k
}
let o = { a: 1 }
keyOf(o, 'a'); //ok
keyOf(o, 'b'); //err
答案 1 :(得分:1)
是的,可以使用Javascript / Typescript完成。有一个typescript module。
从手册中无耻地复制。
nameof(console);
nameof(console.log);
nameof(console["warn"]);
转换为:
"console";
"log";
"warn";
手册中还有更多漂亮的例子。
您问题的解决方案:
interface IMyObject {
myPropertyOther: string;
}
let myObject: IMyObject = {
myProperty: 'Hello world'
};
console.log(myObject[nameof<IMyObject>((o) => o.myProperty)]);
答案 2 :(得分:0)
我创建了一个在运行时获取属性名称的库,即使对于运行时不存在的类型(TypeScript中的接口或类型):
可以在NPM上找到它:@fluffy-spoon/name-of
源代码很简单(仅几行代码):https://github.com/ffMathy/FluffySpoon.JavaScript.NameOf
import { getPropertyName, getDeepPropertyName } from '@fluffy-spoon/name-of';
interface SomeType {
foo: boolean;
someNestedObject: {
bar: string;
}
}
console.log(getPropertyName<SomeType>(x => x.foo)); //prints "foo"
console.log(getPropertyName<SomeType>(x => x.someNestedObject)); //prints "someNestedObject"
console.log(getPropertyName<SomeType>(x => x.someNestedObject.bar)); //prints "bar"
console.log(getDeepPropertyName<SomeType>(x => x.foo)); //prints "foo"
console.log(getDeepPropertyName<SomeType>(x => x.someNestedObject)); //prints "someNestedObject"
console.log(getDeepPropertyName<SomeType>(x => x.someNestedObject.bar)); //prints "someNestedObject.bar"
如果您不想安装NPM软件包。
function getPropertyNameInternal<T = unknown>(expression: (instance: T) => any, options: {
isDeep: boolean
}) {
let propertyThatWasAccessed = "";
var proxy: any = new Proxy({} as any, {
get: function(_: any, prop: any) {
if(options.isDeep) {
if(propertyThatWasAccessed)
propertyThatWasAccessed += ".";
propertyThatWasAccessed += prop;
} else {
propertyThatWasAccessed = prop;
}
return proxy;
}
});
expression(proxy);
return propertyThatWasAccessed;
}
export function getPropertyName<T = unknown>(expression: (instance: T) => any) {
return getPropertyNameInternal(expression, {
isDeep: false
});
}
export function getDeepPropertyName<T = unknown>(expression: (instance: T) => any) {
return getPropertyNameInternal(expression, {
isDeep: true
});
}