2016-10-10 33 views
6

miałem następujący kod:maszynopis Obietnica TS2304 TS2529

function asyncFunc1(): Promise<string> { 
    return new Promise<string>(x => x); 
} 

który wytwarzany następujący błąd:

TS2304: cannot find name 'Promise'

więc zmieniłem go jawnie zadeklarować 'Obietnica':

///<reference path="../typings/modules/bluebird/index.d.ts" /> 

import * as Promise from 'bluebird'; 

function asyncFunc1(): Promise<string> { 
    return new Promise<string>(x => x); 
} 

i teraz pojawia się następujący błąd:

TS2529: Duplicate identifier 'Promise'. Compiler reserves name 'Promise' in top level scope of a module containing async functions

Jak mogę rozwiązać ten paradoks?

+0

Jaki jest twój plik compilerOptions.target w tsconfig? – Paarth

+0

@Paarth Celuję w es5 – Alon

+0

Czy masz zainstalowane inne moduły, które definiują obietnicę, takie jak obietnica core-js lub es6? –

Odpowiedz

4

Obietnice są dostępne tylko w ES6

Jeśli docelową do ES6, kompilator maszynopis wykorzystuje inną bibliotekę bazowej dla typu podstawowego sprawdzenia przed rodzaje zawarte w specyfikacji języka. Upewnij się, że celujesz w ES6.

Promises na maszynie bez kierowania ES6

Jeśli chcesz otrzymać dostęp do definicji Konstruktorów jako metod określonych w specyfikacji es2015, które zostały wdrożone przez przeglądarek i NodeJS (poprzez silnik V8) przed funkcji językowych - jak funkcje strzałek , destrukturyzacja itd. - możesz to zrobić.

To, co chcesz zrobić, to skonfigurować TypeScript do celu es5, nie dołączać i domyślną bibliotekę i odwoływać się do domyślnej biblioteki.

Twój tsconfig może wyglądać tak:

{ 
    "compilerOptions: { 
    "noLib": true, 
    "target": "ES5", 
    } 
    "files": [ 
    "node_modules/typescript/lib/lib.es6.d.ts", 
    "app.ts", 
    ] 
} 

Powyższe przykłady zakłada, że ​​maszynopis jest instalowany bezpośrednio w projekcie. Jeśli nie, możesz zawsze skopiować z folderu instalacji maszynopisu i dołączyć go do projektu.

To rozwiązanie powinno dać ci typowania dla konstruktora Promise, a także wiele innych funkcji, takich jak array.includes() i kilka innych rzeczy. Ma to tę wadę, że nie dostaniesz błędów typu dla rzeczy, które nie są zaimplementowane w przeglądarkach, ale jeśli używasz Promise i tak prawdopodobnie wybierasz tylko nowoczesne przeglądarki lub używasz węzła, w którym kontrolujesz środowisko wykonawcze.

+0

Dzięki za pomaganie mi. Nie otrzymałem powiadomienia o komentarzach do poprzedniej odpowiedzi, ponieważ nie oznaczono mnie tagiem (@Alon). Powiedziałbym ci, że muszę kierować swój projekt na ES6. Mam nadzieję, że znajdziesz inne rozwiązanie, które będzie pasowało do moich ograniczeń :-) – Alon

+0

@Alon Czekaj, więc celujesz w ES6 i nie masz już dostępnej Promesy? Czy używasz już opcji --no-lib kompilator? – nbering

+1

OK Rozgryzłem to. Kiedy opublikowałem to pytanie, zostałem przeniesiony do ES5. Następnie z innego powodu przeniosłem się do ES6, a nie miałem już TS2304, ale TS2529, ponieważ dodałem "import z Bluebird", więc nie zauważyłem, że rozwiązał mój błąd. Teraz, po zapytaniu, dokładnie to sprawdziliśmy i zdaliśmy sobie sprawę, że przejście na ES6 również rozwiązało ten błąd. – Alon

1

Wygląda na to, że TypeScript chroni identyfikator obietnicy. Spróbuj importować jako nazwę inną niż Promise lub użyj innego zestawu typów. W tym wydaniu GitHub TypeScript jest kilka sugestii.

Async/await with Bluebird promises

Kwestia dotyczy korzystania z innej biblioteki obietnicę Async czekają, ale to bardzo sytuacja może dlatego są one ochronę nazwy obietnicy. W szczególności, gdy używamy Async/Await w TypeScript, kompilator konwertuje to na Promise w emitowanym kodzie, więc kompilator próbuje zabezpieczyć konstruktor Promise przed nadpisaniem. Zawsze można oszukać tego kompilatora, ale pamiętaj, aby zadać sobie pytanie, czy to słuszne.

+0

Naprawdę nie potrzebuję Blubird. Dodałem go, aby pozbyć się pierwszego błędu: TS2304: nie można znaleźć nazwy "Obietnica". Przeczytaj uważnie moje pytanie ponownie. – Alon

+0

Następnie musisz kierować reklamy na es6. – nbering

+0

Możesz też pójść gdzieś w połowie i użyć deklaracji biblioteki es6, ale celować w funkcje języka es5. – nbering