Reputation: 28780
I have the following playground with the following code:
export interface Coordinate {
x: number;
y: number;
}
export interface Line {
source: Coordinate;
target: Coordinate;
}
export type Selector<T, K extends keyof T> = (d: { [key: string]: K }) => typeof d[K];
export interface LinkVerticalLineProps {
x: Selector<Coordinate, 'x'>;
y: Selector<Coordinate, 'y'>;
}
class Foo implements LinkVerticalLineProps{
originX: number;
originY: number;
constructor({ x, y }: Coordinate) {
this.originX = x;
this.originY = y;
}
x(other: Coordinate) {
return other.x;
}
y(other: Coordinate) {
return other.x;
}
}
But typescript is not happy.
How I can I satisfy the compiler that the x
function must take an object that has x
for a property and returns typeof d[K]
Upvotes: 1
Views: 19
Reputation: 249536
You can use Pick
to pick out just one property of a type :
export interface Coordinate {
x: number;
y: number;
}
// Use Pick to pick out just one property
export type Selector<T, K extends keyof T> = (d: Pick<T,K>) => T[K]; // you can also use typeof d[K] but it's the same as T[K] but longer
//Does the same thing but less repeating the property names
export type LinkVerticalLineProps = {
[P in keyof Coordinate]: Selector<Coordinate,P>
}
class Foo implements LinkVerticalLineProps{
originX: number;
originY: number;
constructor({ x, y }: Coordinate) {
this.originX = x;
this.originY = y;
}
// We must repeat the Pick, ts will not infer class member argument types
x(other: Pick<Coordinate, 'x'>) {
return other.x;
}
y(other: Pick<Coordinate, 'y'>) {
return other.y;
}
}
Upvotes: 1