2017-09-01 1 views
1

Pour une interface, on peut utiliser Partial<X>, le Mapped Type pour dire "Autoriser toutes les propriétés de X, mais n'en attendre aucune".Existe-t-il un type `Partiel <any>` pour qu'un paramètre de fonction accepte `any` mais soit` void`?

Pour que ce qui suit provoque une erreur du compilateur:

interface X { foo: boolean } 

function doSomething(x: Partial<X>) { 
    let aBoolean: boolean = x.foo; // ERROR: possibly undefined 
} 

doSomething({ foo: true }); // OK 
doSomething({}); // OK 
doSomething(true); // ERROR: Type 'boolean' has no properties in common with 'Partial<X>' 

Je voudrais faire la même chose avec any dire « cette fonction peut accepter quoi que ce soit en tant que paramètre, mais vous ne pouvez pas compter sur quoi que ce soit être là »

function doSomething(x: Partial<any>) { 
    let aBoolean: boolean = x.foo; // OK, but I wish it wasn't 
} 

doSomething({ foo: true }); // OK 
doSomething({}); // OK 
doSomething(true); // OK 
doSomething(/* etc. */); // OK 

Je voudrais que ma fonction d'accepter quoi que ce soit et tout comme un argument, mais à l'intérieur de la fonction que je ne devrais pas être en mesure d'accéder à toutes les propriétés de l'objet sans vérifier leur première. C'est même ok si à l'intérieur de la fonction x a le type void ou never.

Je ne suis pas surpris Partial<any> ne fonctionne pas comme je veux - je suis certainement pas demander « pourquoi ne pas Partial<any> travail la façon dont je souhaite qu'il a fait ». Je demande:

Quel type puis-je utiliser pour le paramètre x tel que:

  1. il accepte les arguments de tout/tous les types
  2. dans la fonction du type de x est quelque chose où chaque propriété est peut-être définie (ou x est de type void, etc.)
+0

Juste rendre 'x' optionnel? [Terrain de jeu TS] (https://www.typescriptlang.org/play/#src=const%20act%20%3D%20 (x% 3F% 3A% 20Partial% 3Cany% 3E)% 20% 3D% 3E% 20 !! x.foo% 3B% 0D% 0A% 0D% 0Aact (% 7B% 20foo% 3A% 20true% 20% 7D)% 3B% 20% 2F% 2F% 20OK% 0D% 0Aact (% 7B% 7D)% 3B% 20% 2F% 2F% 20OK% 0D% 0Aact (vrai)% 3B% 20% 2F% 2F% 20OK% 0D% 0Aact (% 2F *% 20etc% 20 *% 2F)% 3B% 20% 2F% 2F% 20OK) –

+0

Il n'y a pas d'erreur quand vous faites '!! x.foo' dans cet exemple - ou si vous le changez en' {let bar: string = x.foo; } '. Est-ce que je manque quelque chose? – alexanderbird

+0

Le point était que dans la fonction il n'y a aucune garantie des propriétés de 'x', et je voudrais que le type reflète cela. – alexanderbird

Répondre

1

What type can I use for the parameter x such that:

1. it accepts arguments of any/every type 
2. inside the function the type of x is something where every property 
    is possibly undefined (or x is of type void, etc.) 

Il est le type d'objet vide {}, qui est compatible avec presque tous les types et vous permet de passer presque rien à doSomething:

function doSomething(x?: {}) {...} 

doSomething({ foo: true }); // OK 
doSomething({}); // OK 
doSomething(true); // OK 
doSomething(/* etc. */); // OK 

Mais on ne sait rien à ce sujet dans la mise en œuvre, et vous ne pouvez pas l'utiliser sans vérifier d'abord:

function doSomething(x?: {}) { 
    //let b: boolean = x; // error 
    //let o: {} = x; // error when strictNullChecks in on 
    //let bar: string = x.foo; // error 

    if (typeof x === 'boolean') { 
     let b: boolean = x; 
    } 
    if (x !== undefined) { 
     if (hasProperty(ofTypeString, x, 'foo')) { 
      let bar: string = x.foo; 
     } 
    } 
}; 

function hasProperty<T, N extends string>(
    guard: (p: any) => p is T, 
    x: {}, 
    name: N 
): x is {[n in N]: T} 
{ 
    return (name in x) && guard((x as any)[name]); 
} 


function ofTypeString(p: any): p is string { 
    return typeof p === 'string' 
}