如何使用infer从联合类型中提取共同的键?

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

How to use infer to extract a common key from a union type?

问题

interface Base<T extends string> {
   name: T;
}

interface Foo extends Base<'Foo'> {}
interface Bar extends Base<'Bar'> {}
interface Baz extends Base<'Baz'> {}

export type FooBarBaz = Foo | Bar | Baz;

// I want to make a type, which is equivalent to this:
// export type FooBarBazTypes = 'Foo' | 'Bar' | 'Baz';

// But I want to do it with some magic infer stuff.

export type SomeMagicCrap<T> = T extends Base<infer U> ? U : never;

export type FooBarBazTypes = SomeMagicCrap<FooBarBaz> // Should be equivalent to 'Foo' | 'Bar' | 'Baz';

如何提取'Foo''Bar''Baz'?我知道它涉及到infer,但我不记得具体是怎么做的。

英文:

I'm creating a library where I need to use a common type distinguished by name; I need to be able to get the names easily.

interface Base&lt;T extends string&gt; {
   name: T;
}

interface Foo extends Base&lt;&#39;Foo&#39;&gt; {}
interface Bar extends Base&lt;&#39;Bar&#39;&gt; {}
interface Baz extends Base&lt;&#39;Baz&#39;&gt; {}

export type FooBarBaz = Foo | Bar | Baz;

// I want to make a type, which is equivalent to this:
// export type FooBarBazTypes = &#39;Foo&#39; | &#39;Bar&#39; | &#39;Baz&#39;;

// But I want to do it with some magic infer stuff.

export type SomeMagicCrap&lt;T&gt;;

export type FooBarBazTypes = SomeMagicCrap&lt;FooBarBaz &gt; // Should be equivalent to &#39;Foo&#39; | &#39;Bar&#39; | &#39;Baz&#39;;

How can I extract &#39;Foo&#39;, &#39;Bar&#39; and &#39;Baz&#39;? I know it involves infer but I don't remember exactly how.

答案1

得分: 1

你可以检查FooBarBaz联合类型(Foo | Bar | Baz)的值是否扩展了Base,然后通过infer推断传递给Base的泛型值,并将其返回,以生成一个新的联合类型从这些字符串值中。

interface Base<T extends string> {
  name: T;
}

interface Foo extends Base<'Foo'> {}
interface Bar extends Base<'Bar'> {}
interface Baz extends Base<'Baz'> {}

export type FooBarBaz = Foo | Bar | Baz;

type SomeMagicCrap<T> = T extends Base<infer U> ? U : never;

export type FooBarBazTypes = SomeMagicCrap<FooBarBaz>; // 'Foo' | 'Bar' | 'Baz'

TypeScript Playground

英文:

What you can do is check whether values of the FooBarBaz union (Foo | Bar | Baz) extend Base and then infer the generic value passed to Base and return it to generate a new union from those string values.

TypeScript Playground

interface Base&lt;T extends string&gt; {
  name: T;
}

interface Foo extends Base&lt;&#39;Foo&#39;&gt; {}
interface Bar extends Base&lt;&#39;Bar&#39;&gt; {}
interface Baz extends Base&lt;&#39;Baz&#39;&gt; {}

export type FooBarBaz = Foo | Bar | Baz;

type SomeMagicCrap&lt;T&gt; = T extends Base&lt;infer U&gt; ? U : never;

export type FooBarBazTypes = SomeMagicCrap&lt;FooBarBaz&gt;; // &#39;Foo&#39; | &#39;Bar&#39; | &#39;Baz&#39;

huangapple
  • 本文由 发表于 2023年7月27日 23:23:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76781264.html
匿名

发表评论

匿名网友

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

确定