Sereyn
Sereyn

Reputation: 432

Typescript: Constraint on a field of an union type

I created a union type of objects. They all have a field role to differentiate them. Here we have teacher and student:

type User =
    {
        role: "student";
        followClasses: string[];
    } |
    {
        role: "teacher";
        since: number;
    };

Then I wanted to create a function to generate a default student:

const defaultStudent = (): User => ({
    role: "student",
    followClasses: [],
});

But since the return type is the union type User, typescript doesn't know that it's a student, and throw me a warning when I type this:

const student = defaultStudent();

console.log(student.followClasses);
//          Warning here ⮥

How to make the function defaultStudent have a constrained return type (student)?

Upvotes: 0

Views: 638

Answers (1)

bugs
bugs

Reputation: 15313

Extract the two members of the unions as individual types

type Student = {
  role: "student"
  followClasses: string[]
}

type Teacher = {
  role: "teacher"
  since: number
}

and define your union from them directly

type User = Student | Teacher

At this point, you can say that your defaultStudent function doesn't just return a User, you can be more precise than that. It returns a Student.

const defaultStudent = (): Student => ({
  role: "student",
  followClasses: [],
})

const student = defaultStudent()
console.log(student.followClasses) // <-- OK

Upvotes: 2

Related Questions