简体   繁体   中英

TypeScript cannot narrow type

(If you find a better name, please let me know)

I have a function that receives two arguments, a job and an employee. The employee is optional: if the job is scheduled, the employee will be there, otherwise it is not needed.

type Job = {
    name: string;
    schedule?: string;
}

type WorkingEmployee = {
    doWork: (jobName: string) => void
}

function f(job: Job, employee?: WorkingEmployee){
    if (job.schedule) {
        if (employee) {
            employe.do(job.name)
        }
    }
}

However, I know more than this. I know that, if the job is scheduled, then the employee will be there. So I want to enforce this and take advantage of this knowledge:

type ScheduledJob = {
    task: string;
    isDoable: string;
}
type Employee<T> = T extends ScheduledJob ? WorkingEmployee : undefined;

function f<T extends Job>(job: T, employee: Employee<T>){
    if (job.schedule) {
        employee.doWork(job.name);
    }
}

But typescript does not take it: "Object is possibly undefined" , referring to employee.doWork . Why does it not accept it? If schedule is there, then we know for certain that employee is not undefined .

My questions are: 1. Why the compiler does not accept this code? 2. Is there any way of achieving what I am trying to do here?

Generic types are narrowed down when the function gets called. At the time of definition you only know that T is some sort of Job . The typeguard will narrow down the type of job , it won't change what T refers to.

 let a: T, b: T;

 if(a.narrow) {
   // a can be narrowed down, but it is unknown wether the same applies to b. Thus T cannot be narrowed.
 }

You could overload f though (not sure if that works as intended, however it is clearer than a generic function with conditional types):

 function f(job: ScheduledJob, employee: WorkingEmployee);
 function f(job: Job, employee?: WorkingEmployee) {
   //...
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM