javascript - typescript 接口(interface)属性到字符串

标签 javascript typescript

问题/答案 - 2021 年更新

这个问题是6年前问的,当时我对Typescript了解甚少! 我不想删除它,因为还有一些人在阅读这篇文章。

如果你想让一个变量的类型成为另一个变量的属性,你可以使用keyof

例子:

interface User {
    name: string;
    age: number;
}

const nameProperty: keyof User = 'name'; // ok
const ageProperty: keyof User = 'age'; // ok
const emailProperty: keyof User = 'email'; // not ok

如果您想要一个方法接受一个参数,而该参数是另一个参数的属性,您可以使用泛型将这两种类型链接在一起。

使用泛型 + keyof 的例子:

const foo = <TObject extends object>(
    object: TObject,
    property: keyof TObject
) => {
    // You can use object[property] here
};

foo({ a: 1, b: 2 }, 'a'); // ok
foo({ a: 1, b: 2 }, 'b'); // ok
foo({ a: 1, b: 2 }, 'c'); // not ok

使用泛型 + Record 的示例:

const foo = <TKey extends string>(
    object: Record<TKey, unknown>,
    property: TKey
) => {
    // You can use object[property] here
};

foo({ a: 1, b: 2 }, 'a'); // ok
foo({ a: 1, b: 2 }, 'b'); // ok
foo({ a: 1, b: 2 }, 'c'); // not ok

请不要使用这个问题的答案! 如果您在某个时候重命名属性,Typescript 会自动告诉您有错误。


原始问题(2014 年)

目标

我有一个 TypeScript 接口(interface):

interface IInterface{
    id: number;
    name: string;
}

我有一些方法可以输入属性名称(字符串)。

例如:

var methodX = ( property: string, object: any ) => {
    // use object[property]
};

我的问题是,当我调用 methodX 时,我必须在字符串中写入属性名称。

Ex : methodX("name", objectX); 其中 objectX 实现 IInterface

但这是BAD:如果我重命名一个属性(假设我想将name重命名为lastname),我将不得不更新手动我所有的代码。

而且我不想要这种依赖。

由于 typescript 接口(interface)没有 JS 实现,我不明白我为什么不能使用字符串。

我想要类似的东西:methodX(IInterface.name.propertytoString(), objectX);

我是 JS 的新手,您有其他选择吗?

(可选)更多详细信息:为什么我需要将属性作为参数传递,为什么我不使用通用方法?

我使用链接数据的方法:

linkData = <TA, TB>(
    inputList: TA[],
    inputId: string,
    inputPlace: string,
    outputList: TB[],
    outputId: string ) => {

    var mapDestinationItemId: any = {};
    var i: number;
    for ( i = 0; i < outputList.length; ++i ) {
        mapDestinationItemId[outputList[i][outputId]] = outputList[i];
    }

    var itemDestination, itemSource;
    for ( i = 0; i < inputList.length; ++i ) {
        itemDestination = inputList[i];
        itemSource = mapDestinationItemId[itemDestination[inputId]];
        if ( itemSource ) {
            itemDestination[inputPlace] = itemSource;
        }
    }
};

但是TA和TB可以有很多不同的id。所以我不知道如何让它更通用。

最佳答案

2019 年更新:此答案已过时,请查看直接添加到问题中的更新。


basarat 答案是个好主意,但它不适用于接口(interface)。

不能methodX(interfacePropertyToString(()=>interfaceX.porpertyname), objectX)因为interfaceX不是对象.

接口(interface)是抽象的,它们仅用于 TypeScript,在 Javascript 中不存在。

但由于他的回答,我找到了解决方案:在方法中使用参数

最后我们有:

    interfacePropertyToString = ( property: (object: any) => void ) => {
        var chaine = property.toString();
        var arr = chaine.match( /[\s\S]*{[\s\S]*\.([^\.; ]*)[ ;\n]*}/ );
        return arr[1];
    };

我们必须使用 [\s\S] 才能匹配多行,因为 Typescript convert (object: Interface) => {object.code;}到多行函数。

现在你可以随心所欲地使用它了:

        interfacePropertyToString(( o: Interface ) => { o.interfaceProperty});
        interfacePropertyToString( function ( o: Interface  ) { o.interfaceProperty});

关于javascript - typescript 接口(interface)属性到字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29600539/

相关文章:

javascript - 使用 <Link> 从 useState() Hook 传递 setState

javascript - 仅在移动设备上使用 Angular ui Bootstrap Carousel

Angular/RxJS : nested service calls with observables

angular - 在 form.setValues() 上多次触发异步验证

javascript - 为什么这个javascript不解析?

javascript - 从数组创建对象并排序

javascript - 谷歌地图 API v3 是否有单个 IP 的查询限制以及网站每日总限制?

reactjs - 类型中缺少属性 onAuxClickCapture 和 onAuxClick

javascript - Nest 无法解析 USERRepository 的依赖项

javascript - Angular:显示两个类组件之间的差异