Today I Learned

hashrocket A Hashrocket project

convice typescript your literally in the union

We want to pass a string prop that is defined as a union.

function Alert({
  level,
  children,
}: {
  level: "info" | "warn";
  children: ReactNode;
}) {
  const iconName = { info: "info", warn: "alert-triangle" }[level];
  return (
    <View>
      <Feather name={iconName} />
      {children}
    </View>
  );
}

info and alert-triangle are both in the union. Should be groovy, right?

❯ npx tsc
src/components/Alert.ts:666:69 - error TS2322: Type 'string' is not assignable to type '"key" | "type" | ... 267 more ... | undefined'.

Well shoot.

We need to convince typescript that this is no average string. Enter const assertions

const iconName = { info: "hashrocket" as const, warn: "alert-triangle" as const }[level];

And now we get a beautiful error:

❯ npx tsc
src/components/Alert.ts:666:69 - error TS2322: Type "hashrocket" | "alert-triangle" is not assignable to type '"key" | "type" | ... 267 more ... | undefined'.

Change the name back to "info" and we get no errors, with good reason this time. 😎

See More #react TILs
Looking for help? At Hashrocket, our JavaScript experts launch scalable, performant apps on the Web, Android and iOS. Contact us and find out how we can help you.