I have a context provider which streams user data throughout the app.
I have a Student interface:
export interface Student extends User
I would like the provider to return user data of type Student
or User
as follows:
let userData: Student | User = null;
When trying to access a property only available to students, userData?.currentTeam
, VS Code throws the following error:
Property 'currentTeam' does not exist on type 'Student | User'.
Property 'currentTeam' does not exist on type 'User'.ts(2339)
I need help finding out why it is defaulting to the parent interface and how to allow the option of both.
CodePudding user response:
This is standard behavior of unions: unless you do something to check what type you're dealing with, typescript will only allow you to access properties that exist on all members of the union.
Here are some examples of how you can narrow down the type. You can check if the property exists:
if ('currentTeam' in userData) {
console.log(userData.currentTeam);
}
Or if you've created classes (which you may not have), you can use instance of:
if (userData instanceof Student) {
console.log(userData.currentTeam);
}
Or, you can change the types so they all have a property in common, which you can then check to see what type you're dealing with. This is sometimes called a "discriminated union".
interface User {
type: 'user',
// rest of the type here
}
interface Student extends User {
type: 'student',
currentTeam: // something,
// rest of the type here
}
if (userData.type === 'student') {
console.log(userData.currentTeam);
}