Reputation: 52143
Suppose I have an interface like this:
interface User {
id: string;
name: string;
age: number;
}
And I have a method like this:
function getUserValues(properties:string[]):void {
Ajax.fetch("user", properties).then((user:User) => alert(user));
}
And a good call looks like this:
getUserValues("id", "name", "age");
But this will lead to an error:
getUserValues("bogus", "stuff", "what_even_am_i_doing");
What I want is to validate that properties
contains only valid property names of the User
interface. Is this possible? Is there some other way to achieve the safety I'm after here?
Upvotes: 0
Views: 520
Reputation: 325
You can use keyof
to achieve this:
function get<T, K extends keyof T>(obj: T, propertyName: K): void { ... };
Upvotes: 1
Reputation: 275917
What I want is to validate that properties is only valid property names of the User interface. Is there some other way to achieve the safety I'm after here?
You need string literal types in a union:
function getUserValues(properties:('id'|'name'|'age')[]):any[] {
Ajax.fetch("user", properties).then((user:User) => alert(user));
}
You can use code generation to generate the union type from the interfaces for you.
https://basarat.gitbooks.io/typescript/content/docs/types/stringLiteralType.html
Can't be done at the moment. That is no declarative way to say "valid property names of this interface are the members of this string literal union". One can generate code to do the following:
interface User {
id: string;
name: string;
age: number;
}
// Generated. Or kept in sync with the `User` interface manually
type UserPropertyNames = 'id' | 'name' | 'age';
Upvotes: 0