Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kayode-adechinan/d8bdc77e87306bf849d004cf9149e1b0 to your computer and use it in GitHub Desktop.
Save kayode-adechinan/d8bdc77e87306bf849d004cf9149e1b0 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