Reputation: 2507
consider the following code
class FootballService {
getMatches() { return [] }
}
function defineMatchesOnComponent(component: X) {
component.matches = Object.values(component)
.find(property => property instanceof FootballService)
.getMatches();
}
class ComponentA {
constructor(public footballService: FootballService, public otherProp: string) {}
}
class ComponentB {
constructor(public whateverNameYouWant: FootballService, public otherProp: number) {}
}
class ComponentC {
constructor(public otherProp: string) {}
}
const a = new ComponentA(new FootballService(), 'xd');
const b = new ComponentB(new FootballService(), 2);
const c = new ComponentC(true);
is it possible to define such type X
that the following will happen:
defineMatchesOnComponent(a); // should be ok
defineMatchesOnComponent(b); // should be ok
defineMatchesOnComponent(c); // should be type error
In other words is it possible to require at least one property but it may have any name ?
demo: https://stackblitz.com/edit/typescript-fekr1o
Upvotes: 1
Views: 74
Reputation: 249466
Not sure we can do better than a custom error. We can force a type error on the parameter using a conditional type if the union of values in the type (T[keyof T]
) does not contain FootballService
class FootballService {
getMatches() { return [] }
}
function defineMatchesOnComponent<T>(component: T & (FootballService extends T[keyof T] ? {} : "No FootballService property was defined")) {
/* */
}
class ComponentA {
constructor(public footballService: FootballService, public otherProp: string) {}
}
class ComponentB {
constructor(public whateverNameYouWant: FootballService, public otherProp: number) {}
}
class ComponentC {
constructor(public otherProp: boolean) {}
}
const a = new ComponentA(new FootballService(), 'xd');
const b = new ComponentB(new FootballService(), 2);
const c = new ComponentC(true);
defineMatchesOnComponent(a); // should be ok
defineMatchesOnComponent(b); // should be ok
defineMatchesOnComponent(c); // should be type error
Upvotes: 1