From 6ca0a8c951e0e33d403d1e403514b068217cd092 Mon Sep 17 00:00:00 2001 From: Carlos Precioso Date: Sun, 9 Dec 2018 12:52:25 +0100 Subject: [PATCH 1/5] Add ink --- types/ink/index.d.ts | 214 ++++++++++++++++++++++++++++++++++++++++ types/ink/ink-tests.tsx | 32 ++++++ types/ink/tsconfig.json | 18 ++++ types/ink/tslint.json | 1 + 4 files changed, 265 insertions(+) create mode 100644 types/ink/index.d.ts create mode 100644 types/ink/ink-tests.tsx create mode 100644 types/ink/tsconfig.json create mode 100644 types/ink/tslint.json diff --git a/types/ink/index.d.ts b/types/ink/index.d.ts new file mode 100644 index 0000000000..4e6f75911e --- /dev/null +++ b/types/ink/index.d.ts @@ -0,0 +1,214 @@ +// Type definitions for ink 0.5 +// Project: https://github.com/vadimdemedes/ink#readme +// Definitions by: Carlos Precioso +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +/// + +import { ValidationMap } from "prop-types"; + +export interface InkElement {} + +export type InkNode = + | ReadonlyArray + | InkElement + | string + | number + | null; + +export declare function h< + P extends Record, + C extends ComponentClass +>(type: C, props: P, ...children: InkNode[]): InkElement; +export declare function h

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

= {}> = + | ComponentClass + | StatelessComponent; + +export interface InkChildren {} + +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, + callback?: () => void + ): void; + setState( + nextState: (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?>(): (() => CC); +} + +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 declare namespace h { + export const Fragment: InkComponent<{}>; +} +export declare const Fragment: typeof h.Fragment; + +export declare const Color: InkComponent<{ + 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 declare const Bold: InkComponent<{}>; +export declare const Underline: InkComponent<{}>; + +declare global { + namespace JSX { + type Element = InkElement; + + type ElementClass = Component; + type FunctionalElement = StatelessComponent; + + interface ElementAttributesProperty { + props: {}; + } + interface ElementChildrenAttribute { + children: {}; + } + + interface IntrinsicAttributes {} + 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..8aac97d866 --- /dev/null +++ b/types/ink/ink-tests.tsx @@ -0,0 +1,32 @@ +import { Color, Component, Fragment, h, 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..511558273a --- /dev/null +++ b/types/ink/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": ["es6"], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "baseUrl": "../", + "typeRoots": ["../"], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react", + "jsxFactory": "h" + }, + "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" } From 703717f428b06d19fad377748bf3f835ac9580e8 Mon Sep 17 00:00:00 2001 From: Carlos Precioso Date: Sun, 9 Dec 2018 15:38:13 +0100 Subject: [PATCH 2/5] [ink] Upgrade typescript requirement in line with prop-types --- types/ink/index.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/types/ink/index.d.ts b/types/ink/index.d.ts index 4e6f75911e..060112b983 100644 --- a/types/ink/index.d.ts +++ b/types/ink/index.d.ts @@ -2,6 +2,7 @@ // Project: https://github.com/vadimdemedes/ink#readme // Definitions by: Carlos Precioso // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.8 /// From 2b15db7b420e08039a1f60da48d44cc3ee7f1d21 Mon Sep 17 00:00:00 2001 From: Carlos Precioso Date: Sat, 15 Dec 2018 16:46:28 +0100 Subject: [PATCH 3/5] [ink] Fix TS2604 when constructing Color --- types/ink/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/ink/index.d.ts b/types/ink/index.d.ts index 060112b983..5bb62850c6 100644 --- a/types/ink/index.d.ts +++ b/types/ink/index.d.ts @@ -126,7 +126,7 @@ export declare namespace h { } export declare const Fragment: typeof h.Fragment; -export declare const Color: InkComponent<{ +export declare const Color: ComponentClass<{ rgb?: [number, number, number]; hsl?: [number, number, number]; hsv?: [number, number, number]; From 3a0363c7963dc6fce2396a942ce73762023f7002 Mon Sep 17 00:00:00 2001 From: Carlos Precioso Date: Sat, 15 Dec 2018 16:47:19 +0100 Subject: [PATCH 4/5] [ink] Use @jsx pragma instead of jsxFactory config --- types/ink/ink-tests.tsx | 4 +++- types/ink/tsconfig.json | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/types/ink/ink-tests.tsx b/types/ink/ink-tests.tsx index 8aac97d866..3d5d07febc 100644 --- a/types/ink/ink-tests.tsx +++ b/types/ink/ink-tests.tsx @@ -1,4 +1,6 @@ -import { Color, Component, Fragment, h, render } from "ink"; +// @jsx h + +import { Color, Component, Fragment, render } from "ink"; class Counter extends Component<{}, { i: number }> { timer = null as ReturnType | null; diff --git a/types/ink/tsconfig.json b/types/ink/tsconfig.json index 511558273a..7a37ab0861 100644 --- a/types/ink/tsconfig.json +++ b/types/ink/tsconfig.json @@ -11,8 +11,7 @@ "types": [], "noEmit": true, "forceConsistentCasingInFileNames": true, - "jsx": "react", - "jsxFactory": "h" + "jsx": "preserve" }, "files": ["index.d.ts", "ink-tests.tsx"] } From a23fc7d94ae7bcf4b526dada701a47ce94921d11 Mon Sep 17 00:00:00 2001 From: Carlos Precioso Date: Sat, 15 Dec 2018 18:17:55 +0100 Subject: [PATCH 5/5] [ink] Pass linter --- types/ink/index.d.ts | 51 ++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/types/ink/index.d.ts b/types/ink/index.d.ts index 5bb62850c6..f91d83df75 100644 --- a/types/ink/index.d.ts +++ b/types/ink/index.d.ts @@ -8,7 +8,13 @@ import { ValidationMap } from "prop-types"; -export interface InkElement {} +export interface InkElement { + component: InkComponent; + instance: Component | null; + ref: (ref: any) => void; + _props: any; + _children: InkNode[]; +} export type InkNode = | ReadonlyArray @@ -17,36 +23,28 @@ export type InkNode = | number | null; -export declare function h< - P extends Record, - C extends ComponentClass ->(type: C, props: P, ...children: InkNode[]): InkElement; -export declare function h

>( - type: StatelessComponent, +export function h

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

= {}> = | ComponentClass | StatelessComponent; -export interface InkChildren {} - export interface StatelessComponent< P extends Record = {}, C extends Record = {} @@ -65,11 +63,9 @@ export abstract class Component< readonly context: C; setState( - nextState: Partial, - callback?: () => void - ): void; - setState( - nextState: (state: Component["state"]) => Partial, + nextState: + | Partial + | ((state: Component["state"]) => Partial), callback?: () => void ): void; } @@ -104,7 +100,7 @@ export interface Component< ): void; componentDidUpdate?(): void; - getChildContext?>(): (() => CC); + getChildContext?(): (() => Record); } export interface ComponentClass< @@ -121,12 +117,12 @@ export interface ComponentClass< propTypes?: ValidationMap>; } -export declare namespace h { - export const Fragment: InkComponent<{}>; +export namespace h { + const Fragment: InkComponent; } -export declare const Fragment: typeof h.Fragment; +export const Fragment: typeof h.Fragment; -export declare const Color: ComponentClass<{ +export const Color: ComponentClass<{ rgb?: [number, number, number]; hsl?: [number, number, number]; hsv?: [number, number, number]; @@ -184,8 +180,8 @@ export declare const Color: ComponentClass<{ bgWhiteBright?: boolean; }>; -export declare const Bold: InkComponent<{}>; -export declare const Underline: InkComponent<{}>; +export const Bold: InkComponent; +export const Underline: InkComponent; declare global { namespace JSX { @@ -201,7 +197,6 @@ declare global { children: {}; } - interface IntrinsicAttributes {} interface IntrinsicClassAttributes { ref?: (ref: T | null) => void; }