TypeScript require one parameter or the other, but not neither

前端 未结 4 529
不思量自难忘°
不思量自难忘° 2021-01-04 01:50

Say I have this type:

export interface Opts {
  paths?: string | Array,
  path?: string | Array

        
4条回答
  •  长发绾君心
    2021-01-04 02:25

    You are basically looking for an exclusive union type.

    It has been already proposed but unfortunately, in the end, it was declined.

    I found the proposed solutions here not to my liking, mostly because I'm not a fan of fancy and complex types.

    Have you tried with function overloading?

    I was in a similar situation and for me, this was the solution.

    interface Option1 {
      paths: string | string[];
    }
    
    interface Option2 {
      path: string | string[];
    }
    
    function foo(o: Option1): void;
    function foo(o: Option2): void;
    function foo(o: any): any {}
    
    foo({ path: './' });
    foo({ paths: '../' });
    // The folling two lines gives an error: No overload matches this call.
    foo({ paths: './', path: '../' });
    foo({})
    
    

    With arrow function the same code as above would instead be:

    interface Option1 {
      paths: string | string[];
    }
    
    interface Option2 {
      path: string | string[];
    }
    
    interface fooOverload {
      (o: Option1): void;
      (o: Option2): void;
    }
    
    const foo: fooOverload = (o: any) => {};
    
    foo({ path: '2' });
    foo({ paths: '2' });
    // The following two lines gives an error: No overload matches this call.
    foo({ paths: '', path: 'so' });
    foo({});
    

    Hope this helps you out!

提交回复
热议问题