2017-01-19 3 views
8

компилируется без ошибок в машинописном 2.1.5:Разве TypeScript не гарантирует, что обещание разрешено с правильным типом?

function promiseANumber(): Promise<number> { 
    return new Promise(resolve => resolve('definitely not a number')); 
} 

Я ожидал бы ошибкой сообщаться, так как функция решительность вызывается со строкой вместо числа, в соответствии с определением типа.

Почему этот тип несоответствия не обнаружен и не передан компилятором TypeScript?


Edit 1

Глядя на это немного больше, используя определение функции асинхронной вместо компилятор правильно сообщает несоответствие типов. Так что это:

async function promiseANumber(): Promise<number> { 
    return 'definitely not a number'; 
} 

дает

error TS2322: Type '"definitely not a number"' is not assignable to type 'number'. 

Почему эти дела ведут себя по-другому?


Edit 2

Похоже способ сделать компилятор правильно поймать этого явно сказать ему, какой тип обещания вы возвращения. Так что это достаточно:

function promiseANumber() { 
    return new Promise<number>(resolve => resolve('definitely not a number')); 
} 

который компилятор в настоящее время жалуется:

error TS2345: Argument of type '"definitely not a number"' is not assignable to parameter of type 'number | Thenable<number>'. 

Я полагаю, мой вопрос сейчас, почему не может компилятор выводить это, учитывая определение, которое я дал в начале этого вопроса?


Редактировать 3

К счастью, машинопись 2,4 теперь указывает на правильную ошибку для исходного кода! Это связано с его поддержкой return types as inference targets. У этого объявления даже есть образец кода, очень похожий на пример, который я дал изначально.

ответ

3

В этом случае ...

function promiseANumber(): Promise<number> { 
    return new Promise(resolve => resolve('definitely not a number')); 
} 

... причина, почему решительность не ожидает number потому, что он определен как {} при написании new Promise(...), потому что это тип по умолчанию new Promise(). Затем компилятор позволяет присвоить Promise<{}>Promise<number> ... что само по себе вызывает сомнения.

В этом случае ...

async function promiseANumber(): Promise<number> { 
    // type returned is Promise<string>, doesn't match Promise<number> 
    return 'definitely not a number'; 
} 

... тип Возвращается Promise<string> и что не соответствует Promise<number> поэтому компилятор выдает сообщение об ошибке.


В вашем примере с обещанием, вы можете сказать компилятору, чтобы определить, как обещание Promise<number>, выполнив:

function promiseANumber(): Promise<number> { 
    return new Promise<number>(resolve => resolve('definitely not a number')); 
} 

... что вызовет ошибку компиляции, потому что string не присваиваемые number.

+0

В вашем первом примере вы можете явно написать тип, т. Е. 'Const myPromise: Promise = ...'. Это эквивалентно моему первому примеру в моем вопросе. Но это все еще не помогает компилятору. Зачем? – markrian

+0

@markrian Я обновил свой ответ. –

+0

Я вижу, спасибо. Жаль, что компилятор не делает вывод о том, что обещанное обещание - это Promise , основанный на сигнатуре окружающей функции. Это технически невозможно, по какой-то причине, или просто текущее ограничение TypeScript? – markrian

Смежные вопросы