问题/答案 - 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/