Typescript条件泛型类型在返回类型中

huangapple go评论78阅读模式
英文:

Typescript conditional generic type in return type

问题

如何在值不存在时对返回类型的泛型进行条件化?

type Foo = {};

class Bar<P extends Foo> {
    static make<P extends Foo>(a?: P): Bar<P> {
        return new Bar();
    }
}

Bar.make() // 返回 Bar<Foo>

但我需要像这样做:

class Bar<P extends Foo> {
    static make<P extends Foo>(a?: P): Bar<P extends undefined ? never : Foo> {
        return new Bar();
    }
}

Bar.make() // 返回 Bar<never>
Bar.make({}) // 返回 Bar<Foo>
英文:

How to condition the generic of return type if value is not present?

type Foo = {};

class Bar&lt;P extends Foo&gt; {
    static make&lt;P extends Foo&gt;(a?: P): Bar&lt;P&gt; {
        return new Bar();
    }
}

Bar.make() // return Bar&lt;Foo&gt;

But I need to do something like:

class Bar&lt;P extends Foo&gt; {
    static make&lt;P extends Foo&gt;(a?: P): Bar&lt;P extends undefined ? never : Foo&gt; {
        return new Bar();
    }
}

Bar.make() // return Bar&lt;never&gt;
Bar.make({}) // return Bar&lt;Foo&gt;

答案1

得分: 1

You need to apply a default type never.

type Foo = {test: number}; // Example implementation of foo, used in test cases below

class Bar<P extends Foo> {
  // Allow P to extend from Foo, then assign never as the default
  static make<P extends Foo = never>(a?: P): Bar<P> {
    return new Bar();
  }
}

const t1 = Bar.make(); // Bar<never>
const t2 = Bar.make({ test: 2 }) // Bar<{test: 2}> (subtype of Foo)
const t3: Bar<Foo> = Bar.make({ test: 2 }); // Bar<Foo> (explicit typecasting to Bar<Foo>)
const t4 = Bar.make({ bazz: 0 }); // Type error, { bazz: 0 } is not assignable to Foo

Here is a TypeScript Playground link to showcase the different outcomes.

英文:

You need to apply a default type never.

type Foo = {test: number}; // Example implementation of foo, used in test cases below

class Bar&lt;P extends Foo&gt; {
  // Allow P to extend from Foo, then assign never as the default
  static make&lt;P extends Foo = never&gt;(a?: P): Bar&lt;P&gt; {
    return new Bar();
  }
}

const t1 = Bar.make(); // Bar&lt;never&gt;
const t2 = Bar.make({ test: 2 }) // Bar&lt;{test: 2}&gt; (subtype of Foo)
const t3: Bar&lt;Foo&gt; = Bar.make({ test: 2 }); // Bar&lt;Foo&gt; (explicit typecasting to Bar&lt;Foo&gt;)
const t4 = Bar.make({ bazz: 0 }); // Type error, { bazz: 0 } is not assignable to Foo

Here a TypeScript Playground link to showcase the different outcomes.

huangapple
  • 本文由 发表于 2020年1月6日 21:22:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/59612912.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定