Reputation: 1666
I have the following function:
subtract(sub: number | CalendarWeek): T {
if (typeof sub === 'number') {
return new CalendarWeek(...); // Returns a CalendarWeek if sub is a number
}
return 1; // Return number if sub is CalendarWeek
}
Problem is I need to define the type T
such that it depends on the provided type of sub
. That is, T is number
if sub
is CalendarWeek
and CalendarWeek
if sub
is number
.
Upvotes: 2
Views: 516
Reputation: 249476
You can use multiple overloads to return a specific type based on the type of the parameter
function subtract(sub: number): CalendarWeek
function subtract(sub: CalendarWeek): number
function subtract(sub: number | CalendarWeek): number | CalendarWeek {
if (typeof sub === 'number') {
return new CalendarWeek(); // Returns a CalendarWeek if sub is a number
}
return 1; // Return number if sub is CalendarWeek
}
Or we can use conditonal types for a similar effect :
function subtract<T extends number | CalendarWeek>(sub: T): T extends number ? number : CalendarWeek
function subtract(sub: number | CalendarWeek): number | CalendarWeek {
if (typeof sub === 'number') {
return new CalendarWeek(); // Returns a CalendarWeek if sub is a number
}
return 1; // Return number if sub is CalendarWeek
}
Upvotes: 2
Reputation: 327634
The traditional TypeScript way to deal with this is to use overloaded functions. In your case it would be something like:
subtract(sub: number): CalendarWeek;
subtract(sub: CalendarWeek): number;
subtract(sub: number | CalendarWeek): number | CalendarWeek {
if (typeof sub === 'number') {
return new CalendarWeek(...); // Returns a CalendarWeek if sub is a number
}
return 1; // Return number if sub is CalendarWeek
}
You can conceivably use conditional types instead of overloads to represent this in TypeScript 2.8 and above, but it might be more advanced than you're trying to get here.
For interested parties, that solution would look like this:
subtract<T extends number | CalendarWeek>(sub: T): T extends number ? CalendarWeek : number;
subtract(sub: number | CalendarWeek): number | CalendarWeek {
if (typeof sub === 'number') {
return new CalendarWeek(); // Returns a CalendarWeek if sub is a number
}
return 1; // Return number if sub is CalendarWeek
}
Hope that helps. Good luck!
Upvotes: 4