JavaScript name对象属性

时间:2018-11-07 10:15:53

标签: javascript typescript

在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

3 个答案:

答案 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
    });
}