Question/Answer - Update 2021
This questions was asked 6 years ago, and I had very little understanding of Typescript! I don't want to remove it because there are still some people reading this post.
If you want the type of a variable to be a property of another one, you can use keyof.
Example:
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
If you want a method that takes a parameter which is a property of another parameter you can use generics to link both types together.
Example using generics + 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
Example using generics + 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
Don't use this question answers please! Typescript will automatically tell you that there is an error if you rename the property at some point.
Original question (2014)
Objective
I have an interface TypeScript :
interface IInterface{
id: number;
name: string;
}
I have some methods which take in entry the name of a property (string).
Ex :
var methodX = ( property: string, object: any ) => {
// use object[property]
};
My problem is that when i call methodX, I have to write the property name in string.
Ex : methodX("name", objectX); where objectX implements IInterface
But this is BAD : If i rename a property (let's say i want to rename name to lastname) i will have to update manually all my code.
And I don't want this dependency.
As typescript interfaces have no JS implementations, I don't see how I could not use string.
I want to have something like : methodX(IInterface.name.propertytoString(), objectX);
I'm pretty new to JS, do you see an alternative ?
(Optional) More details : Why do I need to pass properties as parameter, and why I don't use a generic method ?
I use methods that link data :
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;
}
}
};
But TA and TB can have a lot of different ids. So i don't see how to make it more generic.
