2017-01-12 11 views
7

To wszystko przy założeniu, że noImplicityAny jest ustawione na true.Używanie nowych funkcji nie działa, chyba że zostaną połączone z interfejsem. Czemu?

Biorąc pod uwagę to:

function Bar() { 
    this.f = 100; 
} 

to nie działa:

let x = new Bar();

Błąd masz jest:

'nowe' wyrażenie, którego cel brakuje skonstruować podpis, domyślnie ma "dowolny" typ.

OK, myślę, że to ma sens.

Jednakże, jeśli dodam interfejs do mieszanki, to działa dobrze:

interface Bar { 
    f: number; 
} 

function Bar() { 
    this.f = 100; 
} 

let x = new Bar(); 
console.log(x.f); 

Po najechaniu Bar widać to jako typ:

interface Bar function Bar(): void

więc mogę to trwa scalanie. Po prostu nie wiem, dlaczego to działa teraz? Czym dokładnie jest ten nowy scalony typ i dlaczego typ zwrotu funkcji Bar() nie jest już domniemany jako any?

+0

Tylko zgadnij, ale interfejs oznacza, że ​​nowy obiekt nie może być typu "dowolny". Wciąż świetne pytanie, chcę wiedzieć więcej :) –

Odpowiedz

3

W języku TypeScript występuje w języku angielskim Declaration Merging. Zasadniczo, jeśli dwa elementy mają taką samą deklarowaną nazwę, TypeScript łączy je w jedną całość. Pozwala to na tworzenie zaawansowanych funkcji, takich jak zapisywanie deklaracji i interfejsów do bibliotek JavaScript stron trzecich, aby były one świadome.

W pierwszym przykładzie kompilator zna typ zwracanej wartości Bar(), który jest void. Nie wie jednak, co zwraca konstruktor, więc przyjmuje się, że new Bar() to any.

Ale kiedy zadeklarować interfejsu o tej samej nazwie, kompilator łączy interface Bar z function Bar(), a interfejs definiuje teraz kształt który przypomina funkcję, więc kompilator podnosi go jako typ new Bar(). Zauważ, że typ Bar() nadal pozostaje void.

+2

Tak, ale moje pytanie brzmi, dlaczego istnienie interfejsu zmienia typ zwracania 'nowego paska()'? – BFree

+0

Interfejs 'Bar' definiuje _shape_ dla funkcji' Bar', której wcześniej kompilator nie mógł znaleźć.Kiedy deklarujesz interfejs, kompilator wie teraz, jaki jest kształt, stąd typ 'new Bar()'. –

0

System typu TypeScript wie, że jest to nowa funkcja konstruktora.

Zamiast funkcji i interfejsu można zdefiniować ją jako pojedynczą klasę.

class Bar { 
    f = 100; 
} 

let x = new Bar(); 
console.log(x.f); 

Jeśli kierujesz się do wersji es5, wygenerowany kod będzie zasadniczo taki sam jak funkcja konstruktora w pytaniu.

Powiązane problemy