Search code examples
reactjstypescriptreact-dom

Can TypeScript make React component instantiation type safe?


I'm very new to TypeScript and React, so apologies for any incorrect or confusing terminology. Basically this is what I'm looking at:

<MyComponent someNumber="40" />

someNumber is a property defined as number, but I'm noticing the following behavior:

  • If I pass a non-number value, e.g. <MyComponent someNumber="foo" /> this still compiles but blows up at runtime
  • If I fail to pass any value, e.g. <MyComponent /> this still compiles even if there's no default value for someNumber

Ideally those two scenarios should fail to compile, but I don't see a way to do this. I'm on TypeScript 2.0.6 if it helps.

This is my tsconfig.json:

{
  "compilerOptions": {
    "outDir": "./dist",
    "allowJs": false,
    "target": "es6",
    "module": "commonjs",
    "jsx": "react"
  },
  "include": [
    "./src/**/*"
  ],
  "files": [
    "typings/index.d.ts"
  ]
}

Solution

  • If you define an interface for the component props then the compiler will check all of that for you:

    interface MyProps {
        someNumber: number;
    }
    interface MyState {}
    class MyComponent extends React.Component<MyProps, MyState> {}
    
    let a1 = <MyComponent someNumber={ 40 } />; // fine
    let a2 = <MyComponent />; // Error: Property 'someNumber' is missing in type ...
    let a3 = <MyComponent someNumber="40" />; // Error: Type 'string' is not assignable to type 'number'
    

    Edit

    The problem had something to do with the react definition files the OP was using.
    Installing the definition using:

    npm install @types/react
    

    Solved the problem.