2017-06-20 35 views
8

Używam TypeScript wersja 2.3.4. Chcę napisać funkcję, która akceptuje obiekt, który musi mieć określone pola. Ale ten obiekt nie powinien zawierać żadnych innych pól. Jak mogę to osiągnąć?TypScript ścisła klasa/interfejs

Teraz działa to tylko wtedy, gdy definiuję obiekt w linii. Ale jeśli użyję innego obiektu z dodatkowymi polami - pozwoli na to kompilator. Co jest całkowicie nie tak.

przykład:

function foo(arg: { a: string }) { // there is tons of fields actually 
    // ... 
} 

foo ({a: "qwerty"}); // No Error - ok 

foo ({a: "qwerty", b: 123}); // Error - ok 

let bar = { 
    a: "qwerty", 
    b: 123 
}; 

foo (bar); // No Error - NOT OK !!! 

sam kod może być writed interfejsy, klasy zgłoszeń typu - to ten sam problem.

Teraz muszę wyodrębnić pola z obiektu ręcznie, aby upewnić się, że nie ma żadnych dodatkowych pól. Ale nie mogę rozpowszechniać tego rozwiązania na ~ 1000 funkcjach (naprawdę tego potrzebuję) w całym kodzie - jest zbyt brudny. Tworzę wrapper API i muszę się upewnić, że nie ma żadnych dodatkowych lub błędnych pól przekazanych do serwera.

+0

Wygląda na to, że jest celowy. Zobacz [ten problem] (https://github.com/Microsoft/TypeScript/issues/13444) i [this] (https://github.com/Microsoft/TypeScript/issues/3755) w celu dodatkowej dyskusji. – Saravana

+0

Saravana, tak, czytam to, ale nie ma odpowiedzi na moje pytanie w tych dyskusjach. Myślę, że lepiej będzie unikać ścisłości interfejsów, ale zostawić to na zajęcia. –

Odpowiedz

2

Funkcja prosicie jest znany jako „exact types”.
Jest to rozważane, to znaczy, ani odrzucone, ani zaakceptowane, a dyskusja nadal trwa.

1

Tak to działa z założenia i nie jestem pewien, czy można to obejść. See the docs, aby uzyskać więcej informacji.

Co też robisz źle - nie możesz być w 100% pewny, co jest wysyłane na serwer. Dopóki przeglądarka nie wie nic o TS, pewna biblioteka może wstrzyknąć dowolne żądanie, czego potrzebuje np. przez nadpisanie metod XmlHttpRequest (np. co najmniej strefowego.

Innym sposobem na łatwe złamanie intencji jest tak proste, jak używanie <any> przed każdym parametrem, który przekazujesz.

TypeScript ma na celu usprawnienie procesu programowania, ale nie sądzę, aby można go było wykorzystać do potrzeb podobnych do twoich. Zwykle jest to objęte pisaniem odpowiednich testów.

+0

Oczywiście wiem, że TS skompilowano do JS, gdzie żadne klasy ani typy nie sprawdzają! Muszę zabezpieczyć moją metodę przed innymi programistami w procesie rozwoju. To wszystko na temat rozwoju.Przykład z prawdziwego zdarzenia: https://codepen.io/HarryBurns/pen/LLWoVa.typescript –

1

Istnieje "sposób", ale trzeba go wdrożyć samodzielnie. To się nazywa „User Defined Type Gwardia”, a wygląda to tak:

interface Test { 
    prop: number; 
} 

function isTest(arg: any): arg is Test { 
    return arg && arg.prop && typeof(arg.prop) == 'number'; 
} 
+0

Lepiej zrobić z Reflection (patrz http://blog.wolksoftware.com/decorators-metadata-reflection-in-typescript-from -novice-to-expert-part-4), więc będzie krótszy, coś w stylu 'check (myObject)'. Lub, w moim przypadku, jest to 'pick (myObject)'. Działa jak funkcja podkreślenia/funkcji 'pick'. –

2

Nekromowanie.
To przychodzi z maszynopisu 2.4:

type foo = { 
    a:string; 
    b:number; 
    opt?:string; 
} 


function test(obj:foo) 
{} 

test({ a:"", b:123, e:"produceError"}); 

i wykonywania na to przedmiot, czy wszystkie parametry są opcjonalne:

function test(obj:foo & object) 
{} 

A jeśli chcesz przekazać albo ciąg lub innego obiektu typu :

function test(obj: string | foo & object) 
{}