如何动态添加/分配类型给 TypeScript 类型对象?

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

How to add/assign Types Dinamically to typescript type object?

问题

我有一个类型,可以是一些预定义的原始字符串

type Definition = "foo" | "bar";


这些情况是函数名称,用户可以调用它们。

用户也可以添加自己的函数,所以类型`Definition`应该添加新的情况。

addFunction('baz', () => console.log('test'));

// 现在定义应该是:"foo" | "bar" | "baz"


我已经尝试了以下两种变体:

变体1:

type Definition = "foo" | "bar" | string;

type ExtendedDefinition = "foo" | "bar" | string;
// 在这种情况下,vscode不会给我自动完成


变体2:

type Definition = "foo" | "bar";
// 也不会提供定义


这个类型`Definition`对于我的包非常关键,我几乎在每个函数中都使用它。

如何实现这个?
英文:

I have an type which can be some predefined primitive string

type Definition = "foo" | "bar";

This cases are function names, which can be called by user.

Users can add their own functions as well, so type Definition should add new case.

addFunction('baz', () => console.log('test'));

// Now definitions should be: "foo" | "bar" | "baz"

I have tried these:
Variant 1:

type Definition = "foo" | "bar" | string;

type ExtendedDefinition = "foo" | "bar" | string; 
// In this case vscode doesn't give me autocomplete

Variant 2:

type Definition = "foo" | "bar";
// doesn't give definitions as well

That type, Definition is key for my package, I use that functions almost in every function.

How can Implement this?

答案1

得分: 1

你可以创建一个被人们称为松散自动完成类型的东西,使用Omit实用程序类型,如下所示:

type ExtendedDefinition = "foo" | "bar" | Omit<string, "foo" | "bar">;

const arg: ExtendedDefinition = "anything"; // -> 不会出现编译错误

这仍然会为字符串联合类型("foo" | "bar")提供自动完成,同时也允许将任何字符串赋给arg

你甚至可以基于这个模式构建自己的自定义实用程序类型LooseAutocomplete

type Definition = "foo" | "bar";
type LooseAutocomplete<T extends string> = T | Omit<string, T>;

const arg: LooseAutocomplete<Definition> = "anything";

type Definition = "foo" | "bar" | string;不起作用,因为编译器将"foo""bar"都推断为string,并将整个联合类型分解为string,这当然不会提供自动完成。现在,Omit所做的是从string类型中删除这个确切的值联合。因此,编译器将联合类型和string类型分开对待。

英文:

What you can do is create something people started calling a loose autocomplete type with the Omit utility type like so:

type ExtendedDefinition = &quot;foo&quot; | &quot;bar&quot; | Omit&lt;string, &quot;foo&quot; | &quot;bar&quot;&gt;;

const arg: ExtendedDefinition = &quot;anything&quot;; // -&gt; no compilation error

This will still give you autocompletion for the string union (&quot;foo&quot; | &quot;bar&quot;) but also allows arg to have any string assigned.

You can even build your own custom utility type LooseAutocomplete based on this pattern:

type Definition = &quot;foo&quot; | &quot;bar&quot;;
type LooseAutocomplete&lt;T extends string&gt; = T | Omit&lt;string, T&gt;;

const arg: LooseAutocomplete&lt;Definition&gt; = &quot;anything&quot;;

type Definition = &quot;foo&quot; | &quot;bar&quot; | string; does not work because the compiler infers both &quot;foo&quot; and &quot;bar&quot; as strings and breaks the whole union down to a string which won't give you autocomplition of course. Now what the Omit does is removing this exact union of values from the string type. Hence the compiler treats the union and the type string seperately.

huangapple
  • 本文由 发表于 2023年6月29日 21:46:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76581643.html
匿名

发表评论

匿名网友

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

确定