TypeScript Conditional Type complains Type not assignable

前端 未结 3 1392
一整个雨季
一整个雨季 2020-12-19 07:50

I am trying to understand how TypeScript conditional type works. Here is my code. There are type errors:

interface MyType {
  name: string;
}

const testFu         


        
3条回答
  •  囚心锁ツ
    2020-12-19 08:03

    The function TestFunc in your code is supposed to return string in every case. I think it is a kind of typo. Let's fix it and go on.

    Later I came up with a more safe solution (I leave my old answer at the bottom). It is better to use overloading. In an overloading you describe the conditional logic and in the function you use union types.

    interface MyType {
      name: string;
    }
    
    function testFunc(
      what: T
    ): T extends MyType ? string : MyType;
    
    function testFunc(what: MyType | string): MyType | string {
      if (typeof what === 'object') {
        return what.name;
      }
      return { name: what };
    }
    

    The old answer:

    interface MyType {
      name: string;
    }
    
    type TestFunc = (what: T) => T extends MyType ? string : MyType;
    
    const testFunc: TestFunc = (what: any) => {
      if (typeof what === 'object') {
        return what.name;
      }
      return { name: what };
    };
    

    Or if you prefer to define the type inline:

    interface MyType {
      name: string;
    }
    
    const testFunc: (what: T) =>
      T extends MyType ? string : MyType =
      (what: any) => {
        if (typeof what === 'object') {
          return what.name;
        }
        return { name: what };
      };
    

    Typescript compiler will handle it like this:

    const a1: MyType = testFunc({ name: 'foo' }); // Type 'string' is not assignable to type 'MyType'.
    
    const a2: MyType = testFunc({ name: 1 }); // Error: Argument of type '{ name: number; }'
    //                                is not assignable to parameter of type 'string | MyType'
    
    const a3: string = testFunc({ name: 'foo' }); // Ok
    
    const a4: string = testFunc('foo'); // Error: Type 'MyType' is not assignable to type 'string'.
    
    const a5: MyType = testFunc('foo'); // Ok
    

提交回复
热议问题