diff --git a/types/ink/index.d.ts b/types/ink/index.d.ts new file mode 100644 index 0000000000..f91d83df75 --- /dev/null +++ b/types/ink/index.d.ts @@ -0,0 +1,210 @@ +// Type definitions for ink 0.5 +// Project: https://github.com/vadimdemedes/ink#readme +// Definitions by: Carlos Precioso +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.8 + +/// + +import { ValidationMap } from "prop-types"; + +export interface InkElement { + component: InkComponent; + instance: Component | null; + ref: (ref: any) => void; + _props: any; + _children: InkNode[]; +} + +export type InkNode = + | ReadonlyArray + | InkElement + | string + | number + | null; + +export function h

>( + type: ComponentClass | StatelessComponent, + props: P, + ...children: InkNode[] +): InkElement; + +export function h( + type: T, + props: JSX.IntrinsicElements[T], + ...children: InkNode[] +): InkElement; + +export function render( + tree: InkElement, + stream?: NodeJS.WriteStream +): (() => void); +export function renderToString(tree: InkElement, prevTree?: InkElement): string; + +export type InkComponent

= {}> = + | ComponentClass + | StatelessComponent; + +export interface StatelessComponent< + P extends Record = {}, + C extends Record = {} +> { + (props: P, context: C): InkElement; + defaultProps?: Record; + propTypes?: ValidationMap>; +} + +export abstract class Component< + P extends Record = {}, + S extends Record = {}, + C extends Record = {} +> { + readonly props: P; + readonly context: C; + + setState( + nextState: + | Partial + | ((state: Component["state"]) => Partial), + callback?: () => void + ): void; +} + +export interface Component< + P extends Record = {}, + S extends Record = {}, + C extends Record = {} +> { + state: S; + + render( + props: Component["props"], + state: Component["state"], + context: Component["state"] + ): InkElement; + + componentWillMount?(): void; + componentDidMount?(): void; + componentWillUnmount?(): void; + componentWillReceiveProps?( + nextProps: Component["props"], + nextState: Component["state"] + ): void; + shouldComponentUpdate?( + nextProps: Component["props"], + nextState: Component["state"] + ): void; + componentWillUpdate?( + nextProps: Component["props"], + nextState: Component["state"] + ): void; + componentDidUpdate?(): void; + + getChildContext?(): (() => Record); +} + +export interface ComponentClass< + P extends Record = {}, + S extends Record = {}, + C extends Record = {} +> { + new (props: Component["props"], context: Component["state"]): Component< + P, + S, + C + >; + defaultProps?: Record; + propTypes?: ValidationMap>; +} + +export namespace h { + const Fragment: InkComponent; +} +export const Fragment: typeof h.Fragment; + +export const Color: ComponentClass<{ + rgb?: [number, number, number]; + hsl?: [number, number, number]; + hsv?: [number, number, number]; + hwb?: [number, number, number]; + hex?: string; + keyword?: string; + bgRgb?: [number, number, number]; + bgHsl?: [number, number, number]; + bgHsv?: [number, number, number]; + bgHwb?: [number, number, number]; + bgHex?: string; + bgKeyword?: string; + reset?: boolean; + bold?: boolean; + dim?: boolean; + italic?: boolean; + underline?: boolean; + inverse?: boolean; + hidden?: boolean; + strikethrough?: boolean; + visible?: boolean; + black?: boolean; + red?: boolean; + green?: boolean; + yellow?: boolean; + blue?: boolean; + magenta?: boolean; + cyan?: boolean; + white?: boolean; + gray?: boolean; + grey?: boolean; + blackBright?: boolean; + redBright?: boolean; + greenBright?: boolean; + yellowBright?: boolean; + blueBright?: boolean; + magentaBright?: boolean; + cyanBright?: boolean; + whiteBright?: boolean; + bgBlack?: boolean; + bgRed?: boolean; + bgGreen?: boolean; + bgYellow?: boolean; + bgBlue?: boolean; + bgMagenta?: boolean; + bgCyan?: boolean; + bgWhite?: boolean; + bgBlackBright?: boolean; + bgRedBright?: boolean; + bgGreenBright?: boolean; + bgYellowBright?: boolean; + bgBlueBright?: boolean; + bgMagentaBright?: boolean; + bgCyanBright?: boolean; + bgWhiteBright?: boolean; +}>; + +export const Bold: InkComponent; +export const Underline: InkComponent; + +declare global { + namespace JSX { + type Element = InkElement; + + type ElementClass = Component; + type FunctionalElement = StatelessComponent; + + interface ElementAttributesProperty { + props: {}; + } + interface ElementChildrenAttribute { + children: {}; + } + + interface IntrinsicClassAttributes { + ref?: (ref: T | null) => void; + } + + interface IntrinsicElements { + div: {}; + span: {}; + br: {}; + } + } +} diff --git a/types/ink/ink-tests.tsx b/types/ink/ink-tests.tsx new file mode 100644 index 0000000000..3d5d07febc --- /dev/null +++ b/types/ink/ink-tests.tsx @@ -0,0 +1,34 @@ +// @jsx h + +import { Color, Component, Fragment, render } from "ink"; + +class Counter extends Component<{}, { i: number }> { + timer = null as ReturnType | null; + state = { i: 0 }; + + constructor() { + super(); + } + + render() { + return ( + + {this.state.i} tests passed + + ); + } + + componentDidMount() { + this.timer = setInterval(() => { + this.setState({ + i: this.state.i + 1 + }); + }, 100); + } + + componentWillUnmount() { + clearInterval(this.timer!); + } +} + +render(); diff --git a/types/ink/tsconfig.json b/types/ink/tsconfig.json new file mode 100644 index 0000000000..7a37ab0861 --- /dev/null +++ b/types/ink/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": ["es6"], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": ["../"], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true, + "jsx": "preserve" + }, + "files": ["index.d.ts", "ink-tests.tsx"] +} diff --git a/types/ink/tslint.json b/types/ink/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/ink/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }