2017-03-08 1 views
0

J'ai ce code:où l'écoulement travaille pour argument de la fonction déstructuré, mais pas pour l'argument non déstructuré

function myFunction({x}: {x?: number} = {}) { 
    console.log(x); 
    return 'foo'; 
} 

function wrapper({x}: {x: number}) { 
    return myFunction({x}); 
} 

function myFunction2({x}: {x?: number} = {}) { 
    console.log(x); 
    return 'foo'; 
} 

function wrapper2(args: {x: number}) { 
    return myFunction2(args); 
} 

myFunction et wrapper font exactement la même chose que myFunction2 et wrapper2, non? Mais flux pense qu'il ya une erreur dans la dernière copie (live demo):

16: return myFunction2(args); 
         ^object type. This type is incompatible with the expected param type of 
10: function myFunction2({x}: {x?: number} = {}) { 
          ^object type 

Est-ce un bug, ou suis-je manque quelque chose et les deux exemples ne sont pas équivalents?

Répondre

1

Voici un exemple plus petit qui illustre la même question:

function myFunction({x}: {x?: number} = {}) { 
    console.log(x); 
    return 'foo'; 
} 

const x: number = 5; 
const obj: {x: number} = {x}; 

myFunction({x}); 
myFunction(obj); 

(tryflow)

Le deuxième appel de fonction, des problèmes de flux cette erreur:

10: myFunction(obj); 
      ^object type. This type is incompatible with the expected param type of 
1: function myFunction({x}: {x?: number} = {}) { 
          ^object type 

La raison de cette arrive n'a rien à voir avec la déstructuration. C'est simplement parce que les objets sont mutables, donc les règles de sous-typage ne s'appliquent pas toujours comme vous le feriez si elles étaient immuables. Lors de la vérification des appels vers myFunction, Flow examine uniquement la signature de type et non l'implémentation. Donc, autant que Flow le sait, myFunction pourrait prendre l'objet mutable qui lui est passé, et mettre sa propriété x à null. Si l'appelant croit que la propriété x ne doit jamais être null, cela enfreindrait ses hypothèses. Dans le premier appel de fonction, nous construisons un nouvel objet, donc Flow peut déduire sans risque qu'il a le type {x?: number}, puisqu'il sait que personne d'autre ne contient de référence.