简体   繁体   中英

Have a optional second parameter in Typescript type

I have these two, very similar types:

import { VariantProps } from "@stitches/core";

export type VariantOption<
  Component extends { [key: symbol | string]: any },
  VariantName extends keyof VariantProps<Component>
> = Extract<VariantProps<Component>[VariantName], string>;

export type Variants<
  Component extends { [key: symbol | string]: any }
> = Extract<VariantProps<Component>, string>;

As can be seen here they are both very similar, the only difference being that the second type doesn't take a second generic parameter, so it doesn't take that index from the VariantProps<Component> type.

Is it possible to merge them both, having the second parameter be optional and change the result based on it being not set?

It would be something like this (not valid syntax):

import { VariantProps } from "@stitches/core";

export type VariantOption<
  Component extends { [key: symbol | string]: any },
  VariantName? extends keyof VariantProps<Component>
> = VariantName ?
        Extract<VariantProps<Component>[VariantName], string> :
        Extract<VariantProps<Component>, string>;

You can set a "default" value for a generic like so:

type Foo<X extends string, Y extends object = {baz: string}> = {
    xParam: X;
    yParam: Y;
}

In your case it would be something like VariantName extends keyof VariantProps<Component> = ??? where ??? is the default type you would want.

Depending on your desired use case, you could get a bit more fancy with conditional types to "change the result based on it being not set" as you say:

// yParam is "null" if second generic type is not specificed
type Foo<X extends string, Y extends object | unknown = unknown> = {
    xParam: X;
    yParam: Y extends object ? Y : null;
}

type Bar = Foo<'hello', {}>;
/*
type Bar = {
    xParam: "hello";
    yParam: {};
}
*/

type Baz = Foo<'world'>;
/*
type Baz = {
    xParam: "world";
    yParam: null;
}
*/

Edit: if I understand your desired behavior based on your question, this might work:

export type VariantOption<
  Component extends { [key: symbol | string]: any },
  VariantName extends keyof VariantProps<Component> | unknown = unknown
> = VariantName extends keyof VariantProps<Component>
  ? Extract<VariantProps<Component>[VariantName], string>
  : Extract<VariantProps<Component>, string>;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM