2016-08-10 3 views
0

Avec le code suivant;Typage dactylographique de TypScript: Requiert une seule propriété

interface ParamTest extends Object { 
    ids?: any; 
    model?: any; 
    params?: any; 
    pageContext?: PageContext; 
} 

class Foo { 
    public callMeWithParamsPlease(params: ParamTest): void{ 

    } 

    public nope() { 
     this.callMeWithParamsPlease("hi"); 
    } 
} 

Je ne sais pas ce que je vais être fourni en tant que paramètre. Mais je sais que au moins un des champs doivent être remplis. Si j'utilise:

export interface ApiServiceOpts extends Object { 
    ids?: any; 
    model?: any; 
    params?: any; 
    pageContext: PageContext; 
} 

Ensuite, il est plus compatible avec la chaîne, comme prévu - parce que la chaîne n'a pas pageContext. Cependant, je ne sais pas avec certitude si le pageContext sera fourni - mais je sais qu'au moins un des champs doit être fourni. Y a-t-il une syntaxe de type dactylographique magique qui permet cela?

Peut-être que quelque chose comme;

interface PageContext {} 


export interface ParamTestId { 
    ids: any; 
} 

export interface ParamTestModel { 
    model: any; 
} 

export interface ParamTestParams { 
    params: any; 
} 

export interface ParamTestPageContext { 
    pageContext: PageContext; 
} 

class Foo { 
    public callMeWithParamsPlease(params: ParamTestId & ParamTestModel & ParamTestParams & ParamTestPageContext): void { 
     params.ids.a = ""; 
     params.model.b = {} 
    } 

    public nope() { 
     this.callMeWithParamsPlease("hi") 
    } 
} 
+0

On ne sait pas ce que vous demandez. '' il n'est plus compatible avec la chaîne '' - quand était-il compatible avec une chaîne, qu'est-ce que c'est "ça"? Non où dans votre code avez-vous un paramètre de chaîne. Aussi, pourquoi étendriez-vous 'Object'? –

Répondre

0

je suggère ce qui suit:

  • Extension Object ne pas ajouter quoi que ce soit, votre interface est déjà un objet. Enlevez ça.
  • Votre type était compatible avec string parce qu'un string est aussi un Object mais vous ne devriez pas compter sur que, au lieu d'utiliser les syndicats de type explicitement indiquer que vous acceptez des objets ou des chaînes, soit

    callMe(params:ParamTest|string) { 
        // params may be a string now regardless of ParamTest's definition. 
    } 
    
  • A ce stade, vous devez utiliser des gardes de type pour vérifier ce que vous avez fait dans les params, à savoir:

    interface ParamTest { 
        ids:string[]; 
        paramContext:string; 
    } 
    class Foo { 
        callMeMaybe(params:ParamTest|string) { 
        if (params instanceof String) { 
         // Cool it's a string. 
         let x = params.charCodeAt(0); 
        } else { 
         let m = params.ids; 
        } 
        } 
    } 
    
+0

Je ne suis pas sûr si vous avez compris la question; 'ParamTest' est compatible avec le type' string'. Même si la fonction accepte explicitement un paramètre ParamTest, une chaîne peut lui être transmise car toutes les propriétés sont facultatives. – David