I would suggest taking the inline type provided and giving it a name (but feel free to continue reading if you prefer not to):
interface Persons {
john: string;
bob: string;
}
You can then utilize keyof Persons
as the parameter type in the method getPerson
:
class PersonList {
persons: Persons = {
john: 'description of john',
bob: 'description of bob'
};
getPerson(name: keyof Persons) {
return this.persons[name];
}
}
Therefore, if pl
is an instance of PersonList
:
console.log(pl.getPerson('john')); // Works
console.log(pl.getPerson('someonenotincluded')); // Error
Live on the playground.
Alternatively, if you would rather keep it inline, you can achieve that by using keyof PersonList['persons']
as the parameter type:
class PersonList {
persons = {
john: 'description of john',
bob: 'description of bob'
};
getPerson(name: keyof PersonList['persons']) {
return this.persons[name];
}
}
Live on the playground.
In a previous comment, you inquired:
Is it possible to implement this in an abstract class? ... It would be great to have the getter implemented in the abstract class, but I haven't figured out a solution yet.
...with reference to this code template:
abstract class AbstractPersonList {
protected abstract persons: { [name: string]: string };
}
class Persons extends AbstractPersonList {
persons = {
john: 'this is john',
}
}
class MorePersons extends AbstractPersonList {
persons = {
bob: 'this is bob',
}
}
You could introduce a parameter in the AbstractPersonList
class:
abstract class AbstractPersonList<T extends {[name: string]: string}> {
protected abstract persons: T;
public getPerson(name: keyof T): string {
return this.persons[name];
}
}
This leads to:
class Persons extends AbstractPersonList<{john: string}> {
persons = {
john: 'this is john',
}
}
class MorePersons extends AbstractPersonList<{bob: string}> {
persons = {
bob: 'this is bob',
}
}
Which results in the behavior you were seeking:
let n = Math.random() < 0.5 ? 'john' : 'bob';
const p = new Persons();
console.log(p.getPerson('john')); // Works
console.log(p.getPerson('bob')); // FAILS: Argument of type '"bob"' is not assignable to parameter of type '"john"'.
console.log(p.getPerson(n)); // FAILS: Argument of type 'string' is not assignable to parameter of type '"john"'.
const mp = new MorePersons();
console.log(mp.getPerson('john')); // FAILS: Argument of type '"john"' is not assignable to parameter of type '"bob"'.
console.log(mp.getPerson('bob')); // Works
console.log(mp.getPerson(n)); // FAILS: Argument of type 'string' is not assignable to parameter of type '"bob"'.
Live on the playground.