Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to declare variable of type A or B when one extends the other in Typescript

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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.

>Solution :

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);
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading