Reputation: 78
I am trying to use conditional typing with Typescript but tsc throwing an error.
interface Player {
name: string;
position: string;
leg: string;
}
interface Coach {
name: string;
licence: string;
}
type Role = 'coach' | 'player';
function getPerson<T extends Role>(role: T): T extends 'coach' ? Coach : Player {
if (role === 'coach') {
return {} as Coach; // Type 'Coach' is not assignable to type 'T extends "coach" ? Coach : Player'
} else {
return {} as Player; // Type 'Player' is not assignable to type 'T extends "coach" ? Coach : Player'
}
}
const person = getPerson('coach'); // const person: Coach
const person2 = getPerson('player'); // const person2: Player
Could someone explain to me why it does not work? And how I should refactor my code to get proper types?
Upvotes: 1
Views: 59
Reputation: 33111
Conditional types does not work in this way in TS.
Let's take a look on next example:
interface Coach {
name: string;
licence: string;
}
type Role = 'coach' | 'player';
function getPerson<T extends string>(role: Role): T extends 'coach' ? Coach : Player {
if (role === 'coach') {
const x = role;
return {} as T extends 'coach' ? Coach : Player; // no error
} else {
return {} as T extends 'coach' ? Coach : Player; // no error
}
}
const person = getPerson('coach'); // const person: Coach
const person2 = getPerson('player'); // const person2: Player
Above example does not helpful at all, but it show you how TS treats your Return type.
You should use overloading
interface Player {
name: string;
position: string;
leg: string;
}
interface Coach {
name: string;
licence: string;
}
type Role = 'coach' | 'player';
function getPerson<T extends 'player'>(role: T): Player
function getPerson<T extends 'coach'>(role: T): Coach
function getPerson<T extends Role>(role: T) {
if (role === 'coach') {
const x = role;
return {} as Coach;
} else {
return {} as Player
}
}
const person = getPerson('coach'); // const person: Coach
const person2 = getPerson('player'); // const person2: Player
Upvotes: 1