Home > Mobile >  Conditional type checking at compile time in Typescript React
Conditional type checking at compile time in Typescript React

Time:02-05

Here is the corresponding TS playground.

The following function uses runtime checking to determine whether its input is a string or a number. Can the same be achieved at compile time?

type complex = string | number;

function fun(c: complex) {
    if (typeof c === "string") {
        return "c is string";
    }
    return "c is number";
}

console.log(fun("abc"));
console.log(fun(123));

Background: I want to create a React-Element which accepts a ReactNode as its child and should wrap it in a paragraph when ReactNode is a string. Wrapping should not occur when the child is not a string.

Here is the corresponding React Playground.

import * as React from "react";
import { render } from "react-dom";

type FunProps = {
  children: React.ReactNode;
};
const Fun = ({ children }: FunProps) => {
  return (
    <>
      {typeof children === "string" && (
        <p style={{ backgroundColor: "yellow" }}>{children}</p>
      )}
      {typeof children !== "string" && children}
    </>
  );
};

render(
  <>
    <Fun>{"123"}</Fun>
    <Fun>{123}</Fun>
  </>,
  document.getElementById("root")
);

CodePudding user response:

Because it is a functional component, i.e. it should be typed as a function.

Type this function that children is a string

type FunProps = {
  children: string;
};

const Fun = ({ children }: FunProps) => {
  return (
    <p style={{ backgroundColor: "yellow" }}>{children}</p>
  );
};

render(
  <>
    <Fun>{"123"}</Fun>
    <Fun>{123}</Fun>
    <Fun><div>555</div></Fun>
  </>,
  document.getElementById("root")
);

CodePudding user response:

Typescript is for compile time types, the types won't affect the runtime behaviour. You cannot use Typescript to automatically run a different function depending on the input type, you will need some conditional to achieve this functionality (similar to the one in your examples)

If you want it "at compile time", you could split the Fun component to two different components which each accepts either a string or a number. Typescript will then ensure that you call it with the correct type and it is done at compile time by simply calling a different function at compile time.

  • Related