Skip to content

Instantly share code, notes, and snippets.

@nicolashery
Last active September 17, 2023 16:58
Show Gist options
  • Save nicolashery/523425710b79edd5d4efa89ff043e2f6 to your computer and use it in GitHub Desktop.
Save nicolashery/523425710b79edd5d4efa89ff043e2f6 to your computer and use it in GitHub Desktop.
TypeScript React JSDoc
node_modules
dist
import * as React from 'react';
export interface Props {
name: string;
enthusiasmLevel?: number;
}
export interface Context {
locale: string;
}
export interface State {
enthusiasmLevel: number;
}
class Hello extends React.Component<Props, State> {
context: Context;
constructor(props: Props) {
super(props);
this.state = {
enthusiasmLevel: props.enthusiasmLevel || 0
};
}
render() {
const { name } = this.props;
const { enthusiasmLevel } = this.state;
const { locale } = this.context;
if (enthusiasmLevel <= 0) {
throw new Error('You could be a little more enthusiastic. :D');
}
let greeting: string;
if (locale === "fr") {
greeting = "Bonjour";
} else {
greeting = "Hello";
}
return (
<div className="hello">
<div className="greeting">
{greeting + " " + name + getExclamationMarks(enthusiasmLevel)}
</div>
</div>
);
}
}
export default Hello;
function getExclamationMarks(numChars: number) {
return Array(numChars + 1).join('!');
}
// @ts-check
import * as React from 'react';
import { Component } from 'react';
// https://github.com/Microsoft/TypeScript/wiki/Type-Checking-JavaScript-Files
// https://github.com/Microsoft/TypeScript/wiki/JSDoc-support-in-JavaScript
/**
* @typedef {Object} Props
* @property {string} name
* @property {string|undefined} enthusiasmLevel
*/
/**
* @typedef {Object} Context
* @property {string} locale
*/
/**
* @typedef {Object} State
* @property {number} enthusiasmLevel
*/
class Hello extends Component {
/**
* @param {Props} props
*/
constructor(props) {
super(props);
// Note: apparently using the @augments syntax doesn't work,
// need to use the weird trick below to have compiler infer
// correct types for props, context, state.
/** @type {Props} */
this.props = this.props || {};
/** @type {Context} */
this.context = this.context || {};
/** @type {State} */
this.state = this.state || {
enthusiasmLevel: props.enthusiasmLevel || 0
};
}
render() {
const { name } = this.props;
const { enthusiasmLevel } = this.state;
const { locale } = this.context;
if (enthusiasmLevel <= 0) {
throw new Error('You could be a little more enthusiastic. :D');
}
/** @type {string} */
let greeting;
if (locale === "fr") {
greeting = "Bonjour";
} else {
greeting = "Hello";
}
return (
<div className="hello">
<div className="greeting">
{greeting + " " + name + getExclamationMarks(enthusiasmLevel)}
</div>
</div>
);
}
}
export default Hello;
/**
* @param {number} numChars
* @returns {string}
*/
function getExclamationMarks(numChars) {
return Array(numChars + 1).join('!');
}
{
"name": "typescript-comments",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "tsc"
},
"author": "",
"license": "MIT",
"dependencies": {
"@types/react": "15.0.34",
"react": "15.6.1",
"typescript": "2.4.1"
}
}
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"strict": true,
"alwaysStrict": true,
"jsx": "react",
"outDir": "dist",
"allowJs": true
},
"files": [
"hello-annotations.tsx",
"hello-jsdoc.js"
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment