2017-06-20 2 views
8

J'utilise TypeScript version 2.3.4. Je veux écrire une fonction qui accepte un objet qui doit avoir des champs spécifiés. Mais cet objet ne doit pas contenir d'autres champs. Comment puis-je atteindre cet objectif?TypeScript classe stricte/interface

Maintenant, cela ne fonctionne que si je définis l'objet en ligne. Mais si j'utilise un autre objet avec des champs supplémentaires - le compilateur le permettra. Ce qui est totalement faux.

Exemple:

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 !!! 

Le même code peut être avec des interfaces, writed classes, déclarations de type - il est le même problème.

Maintenant, je dois extraire manuellement les champs de l'objet pour m'assurer qu'il n'y a pas de champs supplémentaires. Mais je ne peux pas diffuser cette solution sur ~ 1000 fonctions (j'en ai vraiment besoin) partout dans le code - c'est trop compliqué. Je crée un wrapper d'API et je dois m'assurer qu'il n'y a pas de champs supplémentaires ou faux transmis au serveur.

+0

On dirait que c'est intentionnel. Voir [ce problème] (https://github.com/Microsoft/TypeScript/issues/13444) et [this] (https://github.com/Microsoft/TypeScript/issues/3755) pour une discussion supplémentaire. – Saravana

+0

Saravana, oui, j'ai lu ceci, mais il n'y a pas de réponse à ma question dans ces discussions. Je pense qu'il vaudra mieux éviter la rigueur pour les interfaces, mais laissez-le pour les cours. –

Répondre

2

La fonctionnalité que vous demandez est connu sous le nom « exact types ».
Cela est considéré, c'est-à-dire ni rejeté ni accepté, et la discussion continue.

1

Voici comment cela fonctionne par la conception et je ne suis pas sûr que vous pouvez travailler autour de cela. See the docs pour plus d'informations. Ce que vous faites aussi mal - vous ne pouvez pas être sûr à 100% de ce qui est envoyé au serveur. Tant que le navigateur ne sait rien à propos de TS, une bibliothèque peut injecter dans n'importe quelle requête tout ce dont elle a besoin, par exemple. en écrasant les méthodes XmlHttpRequest (c'est ce que fait par exemple au moins la zone.js d'angular).

Une autre façon de casser facilement vos intentions est aussi simple que d'utiliser <any> devant tout paramètre que vous passez. TypeScript est destiné à améliorer votre processus de développement mais je ne pense pas qu'il puisse être utilisé pour des besoins comme le vôtre. Ceci est généralement couvert en écrivant les tests appropriés.

+0

Bien sûr, je sais que TS compilé à JS où pas de classes ou de vérifications de type! Je dois sécuriser ma méthode d'autres développeurs dans le processus de développement. Tout sur le développement.exemple de cas réel: https://codepen.io/HarryBurns/pen/LLWoVa.typescript –

1

Il est "un" moyen, mais vous devez l'implémenter vous-même. Il a appelé un « utilisateur type défini par la Garde » et il ressemble à ceci:

interface Test { 
    prop: number; 
} 

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

Il est préférable de le faire avec réflexion (voir http://blog.wolksoftware.com/decorators-metadata-reflection-in-typescript-from -novice à-part-4 expert, il sera plus court), quelque chose comme 'vérifier (myObject)'. Ou, dans mon cas c'est 'pick (myObject)'. Fonctionne comme la fonction underscore/lodash 'pick'. –

2

Nécromage.
Il vient avec tapuscrit 2.4:

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


function test(obj:foo) 
{} 

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

Et pour l'appliquer est un objet, si tous les paramètres sont facultatifs:

function test(obj:foo & object) 
{} 

Et si vous voulez passer une chaîne ou un autre type d'objet :

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