#How can I fix this conditional conditional types?

8 messages · Page 1 of 1 (latest)

desert pulsar
#

Here is a playground with what I'm trying to achieve
(playground link below #1100173718942122034 message)

My idea is to get these results

// Error because default variant is 'indeterminate'
<FileUploadProgress value={50} />

// OK
<FileUploadProgress variant="determinate" value={50} />

// Error because default status is 'Loading'
<FileUploadProgress error="Error message" />

// OK
<FileUploadProgress status="Failed" error="Error message" />
Discord

Discord is the easiest way to communicate over voice, video, and text. Chat, hang out, and stay close with your friends and communities.

azure perchBOT
#
Famecrew#9507

Preview:```ts
type Status = "Loading" | "Complete" | "Failed"
type Variant = "indeterminate" | "determinate"

type Error<TStatus extends Status> =
TStatus extends "Failed"
? {error: string}
: {error: never}
type Value<TVariant extends Variant> =
TVariant extends "determinate
...```

desert pulsar
#

I want to prevent impossible states in my component but maybe I'm trying to be too strict, wdyt?

desert wolf
#

@desert pulsar I would do this with a discriminated union, not generic conditional types: (a double discriminated union, really)

#
type ErrorAndStatus =
  | { status: "Failed"; error: string }
  | { status?: "Loading" | "Complete" };
type VariantAndValue =
  | { variant?: "indeterminate" }
  | { variant: "determinate"; value: number };

type Status = NonNullable<ErrorAndStatus["status"]>;
type Variant = NonNullable<VariantAndValue["variant"]>;

type FileUploadProgressProps = ErrorAndStatus & VariantAndValue

export const FileUploadProgress = (props: FileUploadProgressProps) => {
  if (props.variant === "determinate") {
    // can access
    props.value;
  }
  if (props.status === "Failed") {
    // can access
    props.error;
  }
  return null;
};
azure perchBOT
desert wolf
#

In this setup, I don't think you can destructure and apply the default that way, since TS needs to know the discriminator prop value before you can access the props that only exist in some cases.

#

I didn't play with the generic approach - it's possible it gives you equivalent external typings as the discriminated union approach, but AFAIK TS doesn't really narrow generics that way, so the implementation would have probably involved casting.