Skip to content

Instantly share code, notes, and snippets.

@Magellol
Created December 9, 2018 18:28
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save Magellol/0c8cbd7b7197e050bce69d716d7843ee to your computer and use it in GitHub Desktop.
Save Magellol/0c8cbd7b7197e050bce69d716d7843ee to your computer and use it in GitHub Desktop.
Override react types to exclusively allow a set of custom intrinsic elements without inheriting from HTML.
// By overriding a subset of the interfaces from the `@types/react` package,
// we're able to strictly type check what our JSX must look like and avoid inheriting from HTML elements (since they're not valid in our environment for instance).
import * as React from 'react';
declare module 'react' {
namespace JSX {
interface ElementChildrenAttribute {
children: {};
}
interface ScenariosAttributes {
foo: string;
}
// TypeScript used this interface to know what kind of intrinsic elements can be rendered.
// https://www.typescriptlang.org/docs/handbook/jsx.html#type-checking
interface IntrinsicElements {
scenarios: ScenariosAttributes;
text: { children: string };
yolo: { isTrulyYolo: boolean };
}
}
}
// Valid type checking.
const App: React.FC = () => (
<scenarios foo="bar">
<text>Hello world</text>
<yolo isTrulyYolo={true} />
</scenarios>
);
// Invalid type checking.
// Property 'div' does not exist on type `JSX.IntrinsicElements`.
const App: React.FC = () => (
<scenarios foo="bar">
<div />
</scenarios>
);
// Invalid type checking.
// Type '{ children: ReactNode; }' is not assignable to type '{ foo: string; }'.
// Property 'foo' is missing in type '{ children: ReactNode; }'.
const App: React.FC = () => (
<scenarios>
<text>Hello world</text>
</scenarios>
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment