Introduction de TypeScript 3.7 fonctions d'affirmation qui peut être utilisé pour restreindre le type d'arguments transmis ou même this
. Les fonctions d'assertion ressemblent à les protections de type définies par l'utilisateur mais vous ajoutez un asserts
avant le prédicat de type. Voici comment vous pourriez mettre en œuvre Extendable
en tant que classe avec add()
comme méthode d'assertion :
class Extendable {
add<K extends PropertyKey, V>(key: K, val: V): asserts this is Record<K, V> {
(this as unknown as Record<K, V>)[key] = val;
}
}
Lorsque vous appelez m.add(key, val)
le compilateur affirme que m
aura une propriété avec une clé ayant le type de key
et une valeur correspondante du type val
. Voici comment l'utiliser :
const m: Extendable = new Extendable();
// ~~~~~~~~~~~~ <-- important annotation here!
m.add('one', 1)
m.add('two', 2)
console.log(m.one.toFixed(2)); // 1.00
console.log(m.two.toExponential(2)); // 2.00e+0
Tout se passe comme prévu. Après avoir appelé m.add('one', 1)
Vous pouvez vous référer à m.one
sans avertissement du compilateur.
Malheureusement, il y a un une mise en garde assez importante ; les fonctions d'assertion ne fonctionnent que si elles ont un type explicitement annoté. Selon la norme demande d'extraction pertinente Cette règle particulière existe pour que l'analyse du flux de contrôle des appels d'assertion potentiels ne déclenche pas circulairement d'autres analyses.
Cela signifie que l'erreur suivante a été commise :
const oops = new Extendable(); // no annotation
oops.add("a", 123); // error!
//~~~~~~~~ <-- Assertions require every name in the call target to be declared with
// an explicit type annotation.
La seule différence est que le type de oops
es déduit être Extendable
au lieu de annoté comme Extendable
comme m
est. Et vous obtenez une erreur en appelant oops.add()
. En fonction de votre cas d'utilisation, cela peut être soit sans importance, soit rédhibitoire.
J'espère que cela vous aidera ; bonne chance !
Lien vers le code