Typescript: dynamic list from array of tuples, no intersection
P粉163951336
2023-08-31 23:02:45
<p><pre class="brush:php;toolbar:false;">const intents = ["primary", "secondary", "accent", "danger"] as const;
const buttonSizes = ["small", "medium", "big"] as const;
type IntentType = (typeof intents)[number];
type SizeType = (typeof buttonSizes)[number];
type ButtonProps = {
intent?: IntentType;
size?: SizeType;
} & {
[K in IntentType as `${Lowercase<K>}`]?: boolean;
};</pre>
<p>In this code, I hope that the Vue component can receive the following properties
</p>
<p>or
like
</p>
<p>now, if I write the code more statically, like:</p>
<pre class="brush:php;toolbar:false;">type ButtonProps = {
intent?: "primary" | "secondary" | "accent" | "danger";
size?: "small" | "medium" | "big";
primary?: boolean;
secondary?: boolean;
accent?: boolean;
danger?: boolean;
}</pre>
<p>It works...but I have some other code that needs to iterate over the intent options and just have it keep repeating...</p>
<p>The first example works, but for some reason VUE throws an error</p>
<blockquote>
<p>Internal server error: [@vue/compiler-sfc] type parameter passed to
DefineProps() must be a literal type or a reference to an interface
or text type. </p>
</blockquote>
<p>This bug appears to be known and being resolved, so it appears</p>
<p>What are other ways to define ButtonProps more dynamically without using intersection? </p>
Given that the error says "Referencing an interface or literal type", I'm assuming that defining
ButtonProps
as an interface extending a base type should work:Playground