TypeScript не может сузить тип - PullRequest
0 голосов
/ 09 апреля 2020

(Если вы найдете более подходящее имя, пожалуйста, дайте мне знать)

У меня есть функция, которая получает два аргумента: работу и сотрудника. Сотрудник необязателен: если работа запланирована, сотрудник будет там, иначе она не нужна.

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)
        }
    }
}

Однако я знаю больше, чем это. Я знаю, что если работа запланирована, то сотрудник будет там. Поэтому я хочу применить это и воспользоваться этими знаниями:

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);
    }
}

Но машинопись не принимает это: "Object is possibly undefined", что относится к employee.doWork. Почему он не принимает это? Если schedule есть, то мы точно знаем, что employee не undefined.

Мои вопросы: 1. Почему компилятор не принимает этот код? 2. Есть ли способ достичь того, что я пытаюсь сделать здесь?

1 Ответ

1 голос
/ 09 апреля 2020

Generi c типы сужаются при вызове функции. На момент определения вы знали, что T - это что-то вроде Job. Типгард сузит тип job, он не изменит то, к чему относится T.

 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.
 }

Вы можете перегрузить f, хотя (не уверен, что это работает как задумано, однако это понятнее, чем обобщенная функция c с условными типами):

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