diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9c72a064b11de..9adf15320d276 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13297,6 +13297,97 @@ namespace ts { getApparentTypeOfContextualType(node); } + function combineSignatures(signatureList: Signature[]): Signature { + // Produce a synthetic signature whose arguments are a union of the parameters of the inferred signatures and whose return type is an intersection + let parameters: Symbol[]; + let minimumParameterCount = Number.POSITIVE_INFINITY; + let maximumRealParameterCount = 0; + let restTypes: Type[]; + let thisTypes: Type[]; + let hasLiteralTypes = false; + + // First, collect aggrgate statistics about all signatures to determine the characteristics of the resulting signature + for (const signature of signatureList) { + if (signature.minArgumentCount < minimumParameterCount) { + minimumParameterCount = signature.minArgumentCount; + } + if (signature.hasRestParameter) { + (restTypes || (restTypes = [])).push(getRestTypeOfSignature(signature)); + } + if (signature.hasLiteralTypes) { + hasLiteralTypes = true; + } + const realParameterCount = length(signature.parameters) - (signature.hasRestParameter ? 1 : 0); + if (maximumRealParameterCount < realParameterCount) { + maximumRealParameterCount = realParameterCount; + } + if (signature.thisParameter) { + (thisTypes || (thisTypes = [])).push(getTypeOfSymbol(signature.thisParameter)); + } + } + + // Then, for every real parameter up to the maximum, combine those parameter types and names into a new symbol + for (let i = 0; i < maximumRealParameterCount; i++) { + const parameterNames: __String[] = []; + const parameterTypes: Type[] = []; + for (const signature of signatureList) { + let type: Type; + const index = signature.thisParameter ? i + 1 : i; + if (index < (signature.hasRestParameter ? signature.parameters.length - 1 : signature.parameters.length)) { + // If the argument is present, add it to the mixed argument + const param = signature.parameters[index]; + if (!contains(parameterNames, param.escapedName)) { + parameterNames.push(param.escapedName); + } + type = getTypeOfSymbol(param); + } + else if (signature.hasRestParameter) { + // Otherwise, if there is a rest type for this signature, add that type + type = getRestTypeOfSignature(signature); + } + else { + // Otherwise, this argument may be `undefined` on some uses + type = undefinedType; + } + if (!contains(parameterTypes, type)) { + parameterTypes.push(type); + } + } + // We do this so the name is reasonable for users + const paramName = escapeLeadingUnderscores(map(parameterNames, unescapeLeadingUnderscores).join("or")); + const paramSymbol = createSymbol(SymbolFlags.FunctionScopedVariable, paramName); + paramSymbol.type = getUnionType(parameterTypes); + (parameters || (parameters = [])).push(paramSymbol); + } + + const hasRestParameter = !!(restTypes && restTypes.length); + if (hasRestParameter) { + const restSymbol = createSymbol(SymbolFlags.FunctionScopedVariable, "rest" as __String); + restSymbol.type = getUnionType(restTypes); + restSymbol.isRestParameter = true; + (parameters || (parameters = [])).push(restSymbol); + } + + let thisParameterSymbol: TransientSymbol; + if (thisTypes && thisTypes.length) { + thisParameterSymbol = createSymbol(SymbolFlags.FunctionScopedVariable, "this" as __String); + thisParameterSymbol.type = getUnionType(thisTypes); + } + + // TODO (weswigham): Merge type predicates? + return createSignature( + /*declaration*/ undefined, + map(flatMap(signatureList, s => s.typeParameters), cloneTypeParameter), + thisParameterSymbol, + parameters, + getIntersectionType(map(signatureList, getReturnTypeOfSignature)), + /*typePredicate*/ undefined, + minimumParameterCount, + hasRestParameter, + hasLiteralTypes + ); + } + // Return the contextual signature for a given expression node. A contextual type provides a // contextual signature if it has a single call signature and if that call signature is non-generic. // If the contextual type is a union type, get the signature from each type possible and if they are @@ -13313,6 +13404,7 @@ namespace ts { } let signatureList: Signature[]; const types = (type).types; + let mismatchedSignatures = false; for (const current of types) { const signature = getContextualCallSignature(current, node); if (signature) { @@ -13321,8 +13413,9 @@ namespace ts { signatureList = [signature]; } else if (!compareSignaturesIdentical(signatureList[0], signature, /*partialMatch*/ false, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true, compareTypesIdentical)) { - // Signatures aren't identical, do not use - return undefined; + // Signatures aren't identical, set flag to union parameter types, intersect return types + signatureList.push(signature); + mismatchedSignatures = true; } else { // Use this signature for contextual union signature @@ -13331,6 +13424,10 @@ namespace ts { } } + if (mismatchedSignatures) { + return combineSignatures(signatureList); + } + // Result is union of signatures collected (return type is union of return types of this signature set) let result: Signature; if (signatureList) { diff --git a/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.symbols b/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.symbols index 530779be29dfd..9c25d62a3edca 100644 --- a/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.symbols +++ b/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.symbols @@ -74,7 +74,9 @@ var x3: IWithCallSignatures | IWithCallSignatures3 = a => /*here a should be any >IWithCallSignatures : Symbol(IWithCallSignatures, Decl(contextualTypeWithUnionTypeCallSignatures.ts, 9, 1)) >IWithCallSignatures3 : Symbol(IWithCallSignatures3, Decl(contextualTypeWithUnionTypeCallSignatures.ts, 15, 1)) >a : Symbol(a, Decl(contextualTypeWithUnionTypeCallSignatures.ts, 32, 52)) +>a.toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >a : Symbol(a, Decl(contextualTypeWithUnionTypeCallSignatures.ts, 32, 52)) +>toString : Symbol(toString, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) // With call signature count mismatch var x4: IWithCallSignatures | IWithCallSignatures4 = a => /*here a should be any*/ a.toString(); diff --git a/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.types b/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.types index 8e1915d47549d..55194fa6da979 100644 --- a/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.types +++ b/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.types @@ -78,12 +78,12 @@ var x3: IWithCallSignatures | IWithCallSignatures3 = a => /*here a should be any >x3 : IWithCallSignatures | IWithCallSignatures3 >IWithCallSignatures : IWithCallSignatures >IWithCallSignatures3 : IWithCallSignatures3 ->a => /*here a should be any*/ a.toString() : (a: any) => any ->a : any ->a.toString() : any ->a.toString : any ->a : any ->toString : any +>a => /*here a should be any*/ a.toString() : (a: string | number) => string +>a : string | number +>a.toString() : string +>a.toString : ((radix?: number) => string) | (() => string) +>a : string | number +>toString : ((radix?: number) => string) | (() => string) // With call signature count mismatch var x4: IWithCallSignatures | IWithCallSignatures4 = a => /*here a should be any*/ a.toString(); diff --git a/tests/baselines/reference/functionExpressionContextualTyping1.errors.txt b/tests/baselines/reference/functionExpressionContextualTyping1.errors.txt new file mode 100644 index 0000000000000..5170118d0f9aa --- /dev/null +++ b/tests/baselines/reference/functionExpressionContextualTyping1.errors.txt @@ -0,0 +1,80 @@ +tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping1.ts(43,17): error TS2339: Property 'toLowerCase' does not exist on type 'string | number'. + Property 'toLowerCase' does not exist on type 'number'. +tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping1.ts(45,7): error TS2339: Property 'toExponential' does not exist on type 'string | number'. + Property 'toExponential' does not exist on type 'string'. +tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping1.ts(52,13): error TS2322: Type '(j: number | T, k: U) => (number | T | U)[]' is not assignable to type '((j: T, k: U) => (T | U)[]) | ((j: number, k: U) => number[])'. + Type '(j: number | T, k: U) => (number | T | U)[]' is not assignable to type '(j: number, k: U) => number[]'. + Type '(number | T | U)[]' is not assignable to type 'number[]'. + Type 'number | T | U' is not assignable to type 'number'. + Type 'T' is not assignable to type 'number'. + + +==== tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping1.ts (3 errors) ==== + // When a function expression with no type parameters and no parameter type annotations + // is contextually typed (section 4.19) by a type T and a contextual signature S can be extracted from T + + enum E { red, blue } + + // A contextual signature S is extracted from a function type T as follows: + // If T is a function type with exactly one call signature, and if that call signature is non- generic, S is that signature. + + var a0: (n: number, s: string) => number = (num, str) => { + num.toExponential(); + return 0; + } + + class Class { + foo() { } + } + + var a1: (c: Class) => number = (a1) => { + a1.foo(); + return 1; + } + + // A contextual signature S is extracted from a function type T as follows: + // If T is a union type, let U be the set of element types in T that have call signatures. + // If each type in U has exactly one call signature and that call signature is non- generic, + // and if all of the signatures are identical ignoring return types, + // then S is a signature with the same parameters and a union of the return types. + var b1: ((s: string, w: boolean) => void) | ((s: string, w: boolean) => string); + b1 = (k, h) => { }; + var b2: typeof a0 | ((n: number, s: string) => string); + b2 = (foo, bar) => { return foo + 1; } + b2 = (foo, bar) => { return "hello"; } + var b3: (name: string, num: number, boo: boolean) => void; + b3 = (name, number) => { }; + + var b4: (n: E) => string = (number = 1) => { return "hello"; }; + var b5: (n: {}) => string = (number = "string") => { return "hello"; }; + + // A contextual signature S is extracted from a function type T as follows: + // Otherwise, no contextual signature can be extracted from T and S is undefined. + var b6: ((s: string, w: boolean) => void) | ((n: number) => number); + var b7: ((s: string, w: boolean) => void) | ((s: string, w: number) => string); + b6 = (k) => { k.toLowerCase() }; + ~~~~~~~~~~~ +!!! error TS2339: Property 'toLowerCase' does not exist on type 'string | number'. +!!! error TS2339: Property 'toLowerCase' does not exist on type 'number'. + b6 = (i) => { + i.toExponential(); + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'toExponential' does not exist on type 'string | number'. +!!! error TS2339: Property 'toExponential' does not exist on type 'string'. + return i; + }; // Per spec, no contextual signature can be extracted in this case. (Otherwise clause) + b7 = (j, m) => { }; // Per spec, no contextual signature can be extracted in this case. (Otherwise clause) + + class C { + constructor() { + var k: ((j: T, k: U) => (T|U)[]) | ((j: number,k :U) => number[]) = (j, k) => { + ~ +!!! error TS2322: Type '(j: number | T, k: U) => (number | T | U)[]' is not assignable to type '((j: T, k: U) => (T | U)[]) | ((j: number, k: U) => number[])'. +!!! error TS2322: Type '(j: number | T, k: U) => (number | T | U)[]' is not assignable to type '(j: number, k: U) => number[]'. +!!! error TS2322: Type '(number | T | U)[]' is not assignable to type 'number[]'. +!!! error TS2322: Type 'number | T | U' is not assignable to type 'number'. +!!! error TS2322: Type 'T' is not assignable to type 'number'. + return [j, k]; + } // Per spec, no contextual signature can be extracted in this case. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/tsxRefInference.js b/tests/baselines/reference/tsxRefInference.js new file mode 100644 index 0000000000000..cd72c821d952d --- /dev/null +++ b/tests/baselines/reference/tsxRefInference.js @@ -0,0 +1,255 @@ +//// [tests/cases/compiler/tsxRefInference.tsx] //// + +//// [index.d.ts] +export as namespace React; +export = React; + +declare namespace React { + interface SyntheticEvent { + bubbles: boolean; + currentTarget: EventTarget & T; + cancelable: boolean; + defaultPrevented: boolean; + eventPhase: number; + isTrusted: boolean; + nativeEvent: Event; + preventDefault(): void; + isDefaultPrevented(): boolean; + stopPropagation(): void; + isPropagationStopped(): boolean; + persist(): void; + // If you thought this should be `EventTarget & T`, see https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12239 + target: EventTarget; + timeStamp: number; + type: string; + } + + interface ChangeEvent extends SyntheticEvent { + target: EventTarget & T; + } + + interface FormEvent extends SyntheticEvent { + } + + interface DOMAttributes { + onChange?: FormEventHandler; + onChangeCapture?: FormEventHandler; + onInput?: FormEventHandler; + onInputCapture?: FormEventHandler; + onReset?: FormEventHandler; + onResetCapture?: FormEventHandler; + onSubmit?: FormEventHandler; + onSubmitCapture?: FormEventHandler; + onInvalid?: FormEventHandler; + onInvalidCapture?: FormEventHandler; + } + + interface HTMLAttributes extends DOMAttributes {} + + interface InputHTMLAttributes extends HTMLAttributes { + onChange?: ChangeEventHandler; + } + + type FormEventHandler = EventHandler>; + type ChangeEventHandler = EventHandler>; + type EventHandler> = (event: E) => void; + type DetailedHTMLProps, T> = ClassAttributes & E; + + interface Attributes { + key?: Key; + } + interface ClassAttributes extends Attributes { + ref?: Ref; + } + + type Key = string | number; + type Ref = string | ((instance: T | null) => any); + + interface Component

extends ComponentLifecycle {} + + interface ComponentLifecycle { + componentWillMount?(): void; + componentDidMount?(): void; + componentWillReceiveProps?(nextProps: Readonly

, nextContext: any): void; + shouldComponentUpdate?(nextProps: Readonly

, nextState: Readonly, nextContext: any): boolean; + componentWillUpdate?(nextProps: Readonly

, nextState: Readonly, nextContext: any): void; + componentDidUpdate?(prevProps: Readonly

, prevState: Readonly, prevContext: any): void; + componentWillUnmount?(): void; + componentDidCatch?(error: Error, errorInfo: ErrorInfo): void; + } + + interface ErrorInfo { + componentStack: string; + } + + interface ReactElement

{ + type: string | ComponentClass

| SFC

; + props: P; + key: Key | null; + } + + interface SFCElement

extends ReactElement

{ + type: SFC

; + } + + type ComponentState = {}; + type ClassType, C extends ComponentClass

> = + & C + & (new (props?: P, context?: any) => T) + & (new (props?: P, context?: any) => { props: P }); + + type CElement> = ComponentElement; + interface ComponentElement> extends ReactElement

{ + type: ComponentClass

; + ref?: Ref; + } + + interface ClassicComponent

extends Component { + replaceState(nextState: S, callback?: () => any): void; + isMounted(): boolean; + getInitialState?(): S; + } + + interface ClassicComponentClass

extends ComponentClass

{ + new (props?: P, context?: any): ClassicComponent; + getDefaultProps?(): P; + } + + type SFC

= StatelessComponent

; + interface StatelessComponent

{ + (props: P & { children?: ReactNode }, context?: any): ReactElement | null; + propTypes?: ValidationMap

; + contextTypes?: ValidationMap; + defaultProps?: Partial

; + displayName?: string; + } + + type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; + type ReactChild = ReactElement | ReactText; + type ReactText = string | number; + // Should be Array but type aliases cannot be recursive + type ReactFragment = {} | Array; + + interface ComponentClass

{ + new (props?: P, context?: any): Component; + propTypes?: ValidationMap

; + contextTypes?: ValidationMap; + childContextTypes?: ValidationMap; + defaultProps?: Partial

; + displayName?: string; + } + + type ValidationMap = {[K in keyof T]?: Validator }; + type Validator = (object: T, key: string, componentName: string, ...rest: any[]) => Error | null; + + function createElement

( + type: SFC

, + props?: Attributes & P, + ...children: ReactNode[]): SFCElement

; + function createElement

( + type: ClassType, ClassicComponentClass

>, + props?: ClassAttributes> & P, + ...children: ReactNode[]): CElement>; + function createElement, C extends ComponentClass

>( + type: ClassType, + props?: ClassAttributes & P, + ...children: ReactNode[]): CElement; + function createElement

( + type: ComponentClass

, + props?: Attributes & P, + ...children: ReactNode[]): ReactElement

; +} + +declare global { + namespace JSX { + interface Element extends React.ReactElement {} + interface ElementClass extends React.Component { + render(): JSX.Element | null | false; + } + interface ElementAttributesProperty { props: {}; } + interface ElementChildrenAttribute { children: {}; } + + interface IntrinsicAttributes extends React.Attributes {} + interface IntrinsicClassAttributes extends React.ClassAttributes {} + + interface IntrinsicElements { + input: React.DetailedHTMLProps, HTMLInputElement>; + } + } +} + +//// [index.tsx] +import React = require("react"); + +interface MyInputProps extends React.DetailedHTMLProps, HTMLInputElement> { + onValid?(): boolean; + onInvalid?(): boolean; +} + +class MyInput implements React.Component { + props: MyInputProps; + render() { + const { onValid, onInvalid, onChange, ...inputProps } = this.props; + return ( + + ); + } + + componentDidMount() {} + + private _onChange(event: React.ChangeEvent) { + // do some validation first... + + // ... then trigger onChange callback, if present: + if (this.props.onChange) { + this.props.onChange(event); + } + } +} + +function someFunction() {} +const x = 0} onChange={someFunction} />; + +//// [index.js] +"use strict"; +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +exports.__esModule = true; +var React = require("react"); +var MyInput = /** @class */ (function () { + function MyInput() { + } + MyInput.prototype.render = function () { + var _a = this.props, onValid = _a.onValid, onInvalid = _a.onInvalid, onChange = _a.onChange, inputProps = __rest(_a, ["onValid", "onInvalid", "onChange"]); + return (React.createElement("input", __assign({}, inputProps, { onChange: this._onChange }))); + }; + MyInput.prototype.componentDidMount = function () { }; + MyInput.prototype._onChange = function (event) { + // do some validation first... + // ... then trigger onChange callback, if present: + if (this.props.onChange) { + this.props.onChange(event); + } + }; + return MyInput; +}()); +function someFunction() { } +var x = React.createElement(MyInput, { ref: function (r) { return 0; }, onChange: someFunction }); diff --git a/tests/baselines/reference/tsxRefInference.symbols b/tests/baselines/reference/tsxRefInference.symbols new file mode 100644 index 0000000000000..7c7a3e10c5896 --- /dev/null +++ b/tests/baselines/reference/tsxRefInference.symbols @@ -0,0 +1,796 @@ +=== tests/cases/compiler/index.tsx === +import React = require("react"); +>React : Symbol(React, Decl(index.tsx, 0, 0)) + +interface MyInputProps extends React.DetailedHTMLProps, HTMLInputElement> { +>MyInputProps : Symbol(MyInputProps, Decl(index.tsx, 0, 32)) +>React.DetailedHTMLProps : Symbol(React.DetailedHTMLProps, Decl(index.d.ts, 51, 74)) +>React : Symbol(React, Decl(index.tsx, 0, 0)) +>DetailedHTMLProps : Symbol(React.DetailedHTMLProps, Decl(index.d.ts, 51, 74)) +>React : Symbol(React, Decl(index.tsx, 0, 0)) +>InputHTMLAttributes : Symbol(React.InputHTMLAttributes, Decl(index.d.ts, 43, 59)) +>HTMLInputElement : Symbol(HTMLInputElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>HTMLInputElement : Symbol(HTMLInputElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + onValid?(): boolean; +>onValid : Symbol(MyInputProps.onValid, Decl(index.tsx, 2, 120)) + + onInvalid?(): boolean; +>onInvalid : Symbol(MyInputProps.onInvalid, Decl(index.tsx, 3, 24)) +} + +class MyInput implements React.Component { +>MyInput : Symbol(MyInput, Decl(index.tsx, 5, 1)) +>React.Component : Symbol(React.Component, Decl(index.d.ts, 62, 57)) +>React : Symbol(React, Decl(index.tsx, 0, 0)) +>Component : Symbol(React.Component, Decl(index.d.ts, 62, 57)) +>MyInputProps : Symbol(MyInputProps, Decl(index.tsx, 0, 32)) + + props: MyInputProps; +>props : Symbol(MyInput.props, Decl(index.tsx, 7, 62)) +>MyInputProps : Symbol(MyInputProps, Decl(index.tsx, 0, 32)) + + render() { +>render : Symbol(MyInput.render, Decl(index.tsx, 8, 24)) + + const { onValid, onInvalid, onChange, ...inputProps } = this.props; +>onValid : Symbol(onValid, Decl(index.tsx, 10, 15)) +>onInvalid : Symbol(onInvalid, Decl(index.tsx, 10, 24)) +>onChange : Symbol(onChange, Decl(index.tsx, 10, 35)) +>inputProps : Symbol(inputProps, Decl(index.tsx, 10, 45)) +>this.props : Symbol(MyInput.props, Decl(index.tsx, 7, 62)) +>this : Symbol(MyInput, Decl(index.tsx, 5, 1)) +>props : Symbol(MyInput.props, Decl(index.tsx, 7, 62)) + + return ( + input : Symbol(JSX.IntrinsicElements.input, Decl(index.d.ts, 171, 37)) + + { ...inputProps } +>inputProps : Symbol(inputProps, Decl(index.tsx, 10, 45)) + + onChange={ this._onChange } +>onChange : Symbol(onChange, Decl(index.tsx, 13, 33)) +>this._onChange : Symbol(MyInput._onChange, Decl(index.tsx, 19, 26)) +>this : Symbol(MyInput, Decl(index.tsx, 5, 1)) +>_onChange : Symbol(MyInput._onChange, Decl(index.tsx, 19, 26)) + + /> + ); + } + + componentDidMount() {} +>componentDidMount : Symbol(MyInput.componentDidMount, Decl(index.tsx, 17, 5)) + + private _onChange(event: React.ChangeEvent) { +>_onChange : Symbol(MyInput._onChange, Decl(index.tsx, 19, 26)) +>event : Symbol(event, Decl(index.tsx, 21, 22)) +>React : Symbol(React, Decl(index.tsx, 0, 0)) +>ChangeEvent : Symbol(React.ChangeEvent, Decl(index.d.ts, 21, 5)) +>HTMLInputElement : Symbol(HTMLInputElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + // do some validation first... + + // ... then trigger onChange callback, if present: + if (this.props.onChange) { +>this.props.onChange : Symbol(React.InputHTMLAttributes.onChange, Decl(index.d.ts, 45, 64)) +>this.props : Symbol(MyInput.props, Decl(index.tsx, 7, 62)) +>this : Symbol(MyInput, Decl(index.tsx, 5, 1)) +>props : Symbol(MyInput.props, Decl(index.tsx, 7, 62)) +>onChange : Symbol(React.InputHTMLAttributes.onChange, Decl(index.d.ts, 45, 64)) + + this.props.onChange(event); +>this.props.onChange : Symbol(React.InputHTMLAttributes.onChange, Decl(index.d.ts, 45, 64)) +>this.props : Symbol(MyInput.props, Decl(index.tsx, 7, 62)) +>this : Symbol(MyInput, Decl(index.tsx, 5, 1)) +>props : Symbol(MyInput.props, Decl(index.tsx, 7, 62)) +>onChange : Symbol(React.InputHTMLAttributes.onChange, Decl(index.d.ts, 45, 64)) +>event : Symbol(event, Decl(index.tsx, 21, 22)) + } + } +} + +function someFunction() {} +>someFunction : Symbol(someFunction, Decl(index.tsx, 29, 1)) + +const x = 0} onChange={someFunction} />; +>x : Symbol(x, Decl(index.tsx, 32, 5)) +>MyInput : Symbol(MyInput, Decl(index.tsx, 5, 1)) +>ref : Symbol(ref, Decl(index.tsx, 32, 18)) +>r : Symbol(r, Decl(index.tsx, 32, 24)) +>onChange : Symbol(onChange, Decl(index.tsx, 32, 31)) +>someFunction : Symbol(someFunction, Decl(index.tsx, 29, 1)) + +=== tests/cases/compiler/node_modules/react/index.d.ts === +export as namespace React; +>React : Symbol(React, Decl(index.d.ts, 0, 0)) + +export = React; +>React : Symbol(React, Decl(index.d.ts, 1, 15)) + +declare namespace React { +>React : Symbol(React, Decl(index.d.ts, 1, 15)) + + interface SyntheticEvent { +>SyntheticEvent : Symbol(SyntheticEvent, Decl(index.d.ts, 3, 25)) +>T : Symbol(T, Decl(index.d.ts, 4, 29)) + + bubbles: boolean; +>bubbles : Symbol(SyntheticEvent.bubbles, Decl(index.d.ts, 4, 33)) + + currentTarget: EventTarget & T; +>currentTarget : Symbol(SyntheticEvent.currentTarget, Decl(index.d.ts, 5, 25)) +>EventTarget : Symbol(EventTarget, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>T : Symbol(T, Decl(index.d.ts, 4, 29)) + + cancelable: boolean; +>cancelable : Symbol(SyntheticEvent.cancelable, Decl(index.d.ts, 6, 39)) + + defaultPrevented: boolean; +>defaultPrevented : Symbol(SyntheticEvent.defaultPrevented, Decl(index.d.ts, 7, 28)) + + eventPhase: number; +>eventPhase : Symbol(SyntheticEvent.eventPhase, Decl(index.d.ts, 8, 34)) + + isTrusted: boolean; +>isTrusted : Symbol(SyntheticEvent.isTrusted, Decl(index.d.ts, 9, 27)) + + nativeEvent: Event; +>nativeEvent : Symbol(SyntheticEvent.nativeEvent, Decl(index.d.ts, 10, 27)) +>Event : Symbol(Event, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + preventDefault(): void; +>preventDefault : Symbol(SyntheticEvent.preventDefault, Decl(index.d.ts, 11, 27)) + + isDefaultPrevented(): boolean; +>isDefaultPrevented : Symbol(SyntheticEvent.isDefaultPrevented, Decl(index.d.ts, 12, 31)) + + stopPropagation(): void; +>stopPropagation : Symbol(SyntheticEvent.stopPropagation, Decl(index.d.ts, 13, 38)) + + isPropagationStopped(): boolean; +>isPropagationStopped : Symbol(SyntheticEvent.isPropagationStopped, Decl(index.d.ts, 14, 32)) + + persist(): void; +>persist : Symbol(SyntheticEvent.persist, Decl(index.d.ts, 15, 40)) + + // If you thought this should be `EventTarget & T`, see https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12239 + target: EventTarget; +>target : Symbol(SyntheticEvent.target, Decl(index.d.ts, 16, 24)) +>EventTarget : Symbol(EventTarget, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + + timeStamp: number; +>timeStamp : Symbol(SyntheticEvent.timeStamp, Decl(index.d.ts, 18, 28)) + + type: string; +>type : Symbol(SyntheticEvent.type, Decl(index.d.ts, 19, 26)) + } + + interface ChangeEvent extends SyntheticEvent { +>ChangeEvent : Symbol(ChangeEvent, Decl(index.d.ts, 21, 5)) +>T : Symbol(T, Decl(index.d.ts, 23, 26)) +>SyntheticEvent : Symbol(SyntheticEvent, Decl(index.d.ts, 3, 25)) +>T : Symbol(T, Decl(index.d.ts, 23, 26)) + + target: EventTarget & T; +>target : Symbol(ChangeEvent.target, Decl(index.d.ts, 23, 56)) +>EventTarget : Symbol(EventTarget, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>T : Symbol(T, Decl(index.d.ts, 23, 26)) + } + + interface FormEvent extends SyntheticEvent { +>FormEvent : Symbol(FormEvent, Decl(index.d.ts, 25, 5)) +>T : Symbol(T, Decl(index.d.ts, 27, 24)) +>SyntheticEvent : Symbol(SyntheticEvent, Decl(index.d.ts, 3, 25)) +>T : Symbol(T, Decl(index.d.ts, 27, 24)) + } + + interface DOMAttributes { +>DOMAttributes : Symbol(DOMAttributes, Decl(index.d.ts, 28, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + + onChange?: FormEventHandler; +>onChange : Symbol(DOMAttributes.onChange, Decl(index.d.ts, 30, 32)) +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + + onChangeCapture?: FormEventHandler; +>onChangeCapture : Symbol(DOMAttributes.onChangeCapture, Decl(index.d.ts, 31, 39)) +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + + onInput?: FormEventHandler; +>onInput : Symbol(DOMAttributes.onInput, Decl(index.d.ts, 32, 46)) +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + + onInputCapture?: FormEventHandler; +>onInputCapture : Symbol(DOMAttributes.onInputCapture, Decl(index.d.ts, 33, 38)) +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + + onReset?: FormEventHandler; +>onReset : Symbol(DOMAttributes.onReset, Decl(index.d.ts, 34, 45)) +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + + onResetCapture?: FormEventHandler; +>onResetCapture : Symbol(DOMAttributes.onResetCapture, Decl(index.d.ts, 35, 38)) +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + + onSubmit?: FormEventHandler; +>onSubmit : Symbol(DOMAttributes.onSubmit, Decl(index.d.ts, 36, 45)) +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + + onSubmitCapture?: FormEventHandler; +>onSubmitCapture : Symbol(DOMAttributes.onSubmitCapture, Decl(index.d.ts, 37, 39)) +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + + onInvalid?: FormEventHandler; +>onInvalid : Symbol(DOMAttributes.onInvalid, Decl(index.d.ts, 38, 46)) +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + + onInvalidCapture?: FormEventHandler; +>onInvalidCapture : Symbol(DOMAttributes.onInvalidCapture, Decl(index.d.ts, 39, 40)) +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 30, 28)) + } + + interface HTMLAttributes extends DOMAttributes {} +>HTMLAttributes : Symbol(HTMLAttributes, Decl(index.d.ts, 41, 5)) +>T : Symbol(T, Decl(index.d.ts, 43, 29)) +>DOMAttributes : Symbol(DOMAttributes, Decl(index.d.ts, 28, 5)) +>T : Symbol(T, Decl(index.d.ts, 43, 29)) + + interface InputHTMLAttributes extends HTMLAttributes { +>InputHTMLAttributes : Symbol(InputHTMLAttributes, Decl(index.d.ts, 43, 59)) +>T : Symbol(T, Decl(index.d.ts, 45, 34)) +>HTMLAttributes : Symbol(HTMLAttributes, Decl(index.d.ts, 41, 5)) +>T : Symbol(T, Decl(index.d.ts, 45, 34)) + + onChange?: ChangeEventHandler; +>onChange : Symbol(InputHTMLAttributes.onChange, Decl(index.d.ts, 45, 64)) +>ChangeEventHandler : Symbol(ChangeEventHandler, Decl(index.d.ts, 49, 58)) +>T : Symbol(T, Decl(index.d.ts, 45, 34)) + } + + type FormEventHandler = EventHandler>; +>FormEventHandler : Symbol(FormEventHandler, Decl(index.d.ts, 47, 5)) +>T : Symbol(T, Decl(index.d.ts, 49, 26)) +>EventHandler : Symbol(EventHandler, Decl(index.d.ts, 50, 62)) +>FormEvent : Symbol(FormEvent, Decl(index.d.ts, 25, 5)) +>T : Symbol(T, Decl(index.d.ts, 49, 26)) + + type ChangeEventHandler = EventHandler>; +>ChangeEventHandler : Symbol(ChangeEventHandler, Decl(index.d.ts, 49, 58)) +>T : Symbol(T, Decl(index.d.ts, 50, 28)) +>EventHandler : Symbol(EventHandler, Decl(index.d.ts, 50, 62)) +>ChangeEvent : Symbol(ChangeEvent, Decl(index.d.ts, 21, 5)) +>T : Symbol(T, Decl(index.d.ts, 50, 28)) + + type EventHandler> = (event: E) => void; +>EventHandler : Symbol(EventHandler, Decl(index.d.ts, 50, 62)) +>E : Symbol(E, Decl(index.d.ts, 51, 22)) +>SyntheticEvent : Symbol(SyntheticEvent, Decl(index.d.ts, 3, 25)) +>event : Symbol(event, Decl(index.d.ts, 51, 56)) +>E : Symbol(E, Decl(index.d.ts, 51, 22)) + + type DetailedHTMLProps, T> = ClassAttributes & E; +>DetailedHTMLProps : Symbol(DetailedHTMLProps, Decl(index.d.ts, 51, 74)) +>E : Symbol(E, Decl(index.d.ts, 52, 27)) +>HTMLAttributes : Symbol(HTMLAttributes, Decl(index.d.ts, 41, 5)) +>T : Symbol(T, Decl(index.d.ts, 52, 55)) +>T : Symbol(T, Decl(index.d.ts, 52, 55)) +>ClassAttributes : Symbol(ClassAttributes, Decl(index.d.ts, 56, 5)) +>T : Symbol(T, Decl(index.d.ts, 52, 55)) +>E : Symbol(E, Decl(index.d.ts, 52, 27)) + + interface Attributes { +>Attributes : Symbol(Attributes, Decl(index.d.ts, 52, 84)) + + key?: Key; +>key : Symbol(Attributes.key, Decl(index.d.ts, 54, 26)) +>Key : Symbol(Key, Decl(index.d.ts, 59, 5)) + } + interface ClassAttributes extends Attributes { +>ClassAttributes : Symbol(ClassAttributes, Decl(index.d.ts, 56, 5)) +>T : Symbol(T, Decl(index.d.ts, 57, 30)) +>Attributes : Symbol(Attributes, Decl(index.d.ts, 52, 84)) + + ref?: Ref; +>ref : Symbol(ClassAttributes.ref, Decl(index.d.ts, 57, 53)) +>Ref : Symbol(Ref, Decl(index.d.ts, 61, 31)) +>T : Symbol(T, Decl(index.d.ts, 57, 30)) + } + + type Key = string | number; +>Key : Symbol(Key, Decl(index.d.ts, 59, 5)) + + type Ref = string | ((instance: T | null) => any); +>Ref : Symbol(Ref, Decl(index.d.ts, 61, 31)) +>T : Symbol(T, Decl(index.d.ts, 62, 13)) +>instance : Symbol(instance, Decl(index.d.ts, 62, 29)) +>T : Symbol(T, Decl(index.d.ts, 62, 13)) + + interface Component

extends ComponentLifecycle {} +>Component : Symbol(Component, Decl(index.d.ts, 62, 57)) +>P : Symbol(P, Decl(index.d.ts, 64, 24)) +>S : Symbol(S, Decl(index.d.ts, 64, 31)) +>ComponentLifecycle : Symbol(ComponentLifecycle, Decl(index.d.ts, 64, 75)) +>P : Symbol(P, Decl(index.d.ts, 64, 24)) +>S : Symbol(S, Decl(index.d.ts, 64, 31)) + + interface ComponentLifecycle { +>ComponentLifecycle : Symbol(ComponentLifecycle, Decl(index.d.ts, 64, 75)) +>P : Symbol(P, Decl(index.d.ts, 66, 33)) +>S : Symbol(S, Decl(index.d.ts, 66, 35)) + + componentWillMount?(): void; +>componentWillMount : Symbol(ComponentLifecycle.componentWillMount, Decl(index.d.ts, 66, 40)) + + componentDidMount?(): void; +>componentDidMount : Symbol(ComponentLifecycle.componentDidMount, Decl(index.d.ts, 67, 36)) + + componentWillReceiveProps?(nextProps: Readonly

, nextContext: any): void; +>componentWillReceiveProps : Symbol(ComponentLifecycle.componentWillReceiveProps, Decl(index.d.ts, 68, 35)) +>nextProps : Symbol(nextProps, Decl(index.d.ts, 69, 35)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>P : Symbol(P, Decl(index.d.ts, 66, 33)) +>nextContext : Symbol(nextContext, Decl(index.d.ts, 69, 58)) + + shouldComponentUpdate?(nextProps: Readonly

, nextState: Readonly, nextContext: any): boolean; +>shouldComponentUpdate : Symbol(ComponentLifecycle.shouldComponentUpdate, Decl(index.d.ts, 69, 83)) +>nextProps : Symbol(nextProps, Decl(index.d.ts, 70, 31)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>P : Symbol(P, Decl(index.d.ts, 66, 33)) +>nextState : Symbol(nextState, Decl(index.d.ts, 70, 54)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>S : Symbol(S, Decl(index.d.ts, 66, 35)) +>nextContext : Symbol(nextContext, Decl(index.d.ts, 70, 78)) + + componentWillUpdate?(nextProps: Readonly

, nextState: Readonly, nextContext: any): void; +>componentWillUpdate : Symbol(ComponentLifecycle.componentWillUpdate, Decl(index.d.ts, 70, 106)) +>nextProps : Symbol(nextProps, Decl(index.d.ts, 71, 29)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>P : Symbol(P, Decl(index.d.ts, 66, 33)) +>nextState : Symbol(nextState, Decl(index.d.ts, 71, 52)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>S : Symbol(S, Decl(index.d.ts, 66, 35)) +>nextContext : Symbol(nextContext, Decl(index.d.ts, 71, 76)) + + componentDidUpdate?(prevProps: Readonly

, prevState: Readonly, prevContext: any): void; +>componentDidUpdate : Symbol(ComponentLifecycle.componentDidUpdate, Decl(index.d.ts, 71, 101)) +>prevProps : Symbol(prevProps, Decl(index.d.ts, 72, 28)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>P : Symbol(P, Decl(index.d.ts, 66, 33)) +>prevState : Symbol(prevState, Decl(index.d.ts, 72, 51)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>S : Symbol(S, Decl(index.d.ts, 66, 35)) +>prevContext : Symbol(prevContext, Decl(index.d.ts, 72, 75)) + + componentWillUnmount?(): void; +>componentWillUnmount : Symbol(ComponentLifecycle.componentWillUnmount, Decl(index.d.ts, 72, 100)) + + componentDidCatch?(error: Error, errorInfo: ErrorInfo): void; +>componentDidCatch : Symbol(ComponentLifecycle.componentDidCatch, Decl(index.d.ts, 73, 38)) +>error : Symbol(error, Decl(index.d.ts, 74, 27)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>errorInfo : Symbol(errorInfo, Decl(index.d.ts, 74, 40)) +>ErrorInfo : Symbol(ErrorInfo, Decl(index.d.ts, 75, 5)) + } + + interface ErrorInfo { +>ErrorInfo : Symbol(ErrorInfo, Decl(index.d.ts, 75, 5)) + + componentStack: string; +>componentStack : Symbol(ErrorInfo.componentStack, Decl(index.d.ts, 77, 25)) + } + + interface ReactElement

{ +>ReactElement : Symbol(ReactElement, Decl(index.d.ts, 79, 5)) +>P : Symbol(P, Decl(index.d.ts, 81, 27)) + + type: string | ComponentClass

| SFC

; +>type : Symbol(ReactElement.type, Decl(index.d.ts, 81, 31)) +>ComponentClass : Symbol(ComponentClass, Decl(index.d.ts, 127, 66)) +>P : Symbol(P, Decl(index.d.ts, 81, 27)) +>SFC : Symbol(SFC, Decl(index.d.ts, 112, 5)) +>P : Symbol(P, Decl(index.d.ts, 81, 27)) + + props: P; +>props : Symbol(ReactElement.props, Decl(index.d.ts, 82, 50)) +>P : Symbol(P, Decl(index.d.ts, 81, 27)) + + key: Key | null; +>key : Symbol(ReactElement.key, Decl(index.d.ts, 83, 17)) +>Key : Symbol(Key, Decl(index.d.ts, 59, 5)) + } + + interface SFCElement

extends ReactElement

{ +>SFCElement : Symbol(SFCElement, Decl(index.d.ts, 85, 5)) +>P : Symbol(P, Decl(index.d.ts, 87, 25)) +>ReactElement : Symbol(ReactElement, Decl(index.d.ts, 79, 5)) +>P : Symbol(P, Decl(index.d.ts, 87, 25)) + + type: SFC

; +>type : Symbol(SFCElement.type, Decl(index.d.ts, 87, 53)) +>SFC : Symbol(SFC, Decl(index.d.ts, 112, 5)) +>P : Symbol(P, Decl(index.d.ts, 87, 25)) + } + + type ComponentState = {}; +>ComponentState : Symbol(ComponentState, Decl(index.d.ts, 89, 5)) + + type ClassType, C extends ComponentClass

> = +>ClassType : Symbol(ClassType, Decl(index.d.ts, 91, 29)) +>P : Symbol(P, Decl(index.d.ts, 92, 19)) +>T : Symbol(T, Decl(index.d.ts, 92, 21)) +>Component : Symbol(Component, Decl(index.d.ts, 62, 57)) +>P : Symbol(P, Decl(index.d.ts, 92, 19)) +>ComponentState : Symbol(ComponentState, Decl(index.d.ts, 89, 5)) +>C : Symbol(C, Decl(index.d.ts, 92, 61)) +>ComponentClass : Symbol(ComponentClass, Decl(index.d.ts, 127, 66)) +>P : Symbol(P, Decl(index.d.ts, 92, 19)) + + & C +>C : Symbol(C, Decl(index.d.ts, 92, 61)) + + & (new (props?: P, context?: any) => T) +>props : Symbol(props, Decl(index.d.ts, 94, 16)) +>P : Symbol(P, Decl(index.d.ts, 92, 19)) +>context : Symbol(context, Decl(index.d.ts, 94, 26)) +>T : Symbol(T, Decl(index.d.ts, 92, 21)) + + & (new (props?: P, context?: any) => { props: P }); +>props : Symbol(props, Decl(index.d.ts, 95, 16)) +>P : Symbol(P, Decl(index.d.ts, 92, 19)) +>context : Symbol(context, Decl(index.d.ts, 95, 26)) +>props : Symbol(props, Decl(index.d.ts, 95, 46)) +>P : Symbol(P, Decl(index.d.ts, 92, 19)) + + type CElement> = ComponentElement; +>CElement : Symbol(CElement, Decl(index.d.ts, 95, 59)) +>P : Symbol(P, Decl(index.d.ts, 97, 18)) +>T : Symbol(T, Decl(index.d.ts, 97, 20)) +>Component : Symbol(Component, Decl(index.d.ts, 62, 57)) +>P : Symbol(P, Decl(index.d.ts, 97, 18)) +>ComponentState : Symbol(ComponentState, Decl(index.d.ts, 89, 5)) +>ComponentElement : Symbol(ComponentElement, Decl(index.d.ts, 97, 86)) +>P : Symbol(P, Decl(index.d.ts, 97, 18)) +>T : Symbol(T, Decl(index.d.ts, 97, 20)) + + interface ComponentElement> extends ReactElement

{ +>ComponentElement : Symbol(ComponentElement, Decl(index.d.ts, 97, 86)) +>P : Symbol(P, Decl(index.d.ts, 98, 31)) +>T : Symbol(T, Decl(index.d.ts, 98, 33)) +>Component : Symbol(Component, Decl(index.d.ts, 62, 57)) +>P : Symbol(P, Decl(index.d.ts, 98, 31)) +>ComponentState : Symbol(ComponentState, Decl(index.d.ts, 89, 5)) +>ReactElement : Symbol(ReactElement, Decl(index.d.ts, 79, 5)) +>P : Symbol(P, Decl(index.d.ts, 98, 31)) + + type: ComponentClass

; +>type : Symbol(ComponentElement.type, Decl(index.d.ts, 98, 99)) +>ComponentClass : Symbol(ComponentClass, Decl(index.d.ts, 127, 66)) +>P : Symbol(P, Decl(index.d.ts, 98, 31)) + + ref?: Ref; +>ref : Symbol(ComponentElement.ref, Decl(index.d.ts, 99, 32)) +>Ref : Symbol(Ref, Decl(index.d.ts, 61, 31)) +>T : Symbol(T, Decl(index.d.ts, 98, 33)) + } + + interface ClassicComponent

extends Component { +>ClassicComponent : Symbol(ClassicComponent, Decl(index.d.ts, 101, 5)) +>P : Symbol(P, Decl(index.d.ts, 103, 31)) +>S : Symbol(S, Decl(index.d.ts, 103, 38)) +>Component : Symbol(Component, Decl(index.d.ts, 62, 57)) +>P : Symbol(P, Decl(index.d.ts, 103, 31)) +>S : Symbol(S, Decl(index.d.ts, 103, 38)) + + replaceState(nextState: S, callback?: () => any): void; +>replaceState : Symbol(ClassicComponent.replaceState, Decl(index.d.ts, 103, 72)) +>nextState : Symbol(nextState, Decl(index.d.ts, 104, 21)) +>S : Symbol(S, Decl(index.d.ts, 103, 38)) +>callback : Symbol(callback, Decl(index.d.ts, 104, 34)) + + isMounted(): boolean; +>isMounted : Symbol(ClassicComponent.isMounted, Decl(index.d.ts, 104, 63)) + + getInitialState?(): S; +>getInitialState : Symbol(ClassicComponent.getInitialState, Decl(index.d.ts, 105, 29)) +>S : Symbol(S, Decl(index.d.ts, 103, 38)) + } + + interface ClassicComponentClass

extends ComponentClass

{ +>ClassicComponentClass : Symbol(ClassicComponentClass, Decl(index.d.ts, 107, 5)) +>P : Symbol(P, Decl(index.d.ts, 109, 36)) +>ComponentClass : Symbol(ComponentClass, Decl(index.d.ts, 127, 66)) +>P : Symbol(P, Decl(index.d.ts, 109, 36)) + + new (props?: P, context?: any): ClassicComponent; +>props : Symbol(props, Decl(index.d.ts, 110, 13)) +>P : Symbol(P, Decl(index.d.ts, 109, 36)) +>context : Symbol(context, Decl(index.d.ts, 110, 23)) +>ClassicComponent : Symbol(ClassicComponent, Decl(index.d.ts, 101, 5)) +>P : Symbol(P, Decl(index.d.ts, 109, 36)) +>ComponentState : Symbol(ComponentState, Decl(index.d.ts, 89, 5)) + + getDefaultProps?(): P; +>getDefaultProps : Symbol(ClassicComponentClass.getDefaultProps, Decl(index.d.ts, 110, 76)) +>P : Symbol(P, Decl(index.d.ts, 109, 36)) + } + + type SFC

= StatelessComponent

; +>SFC : Symbol(SFC, Decl(index.d.ts, 112, 5)) +>P : Symbol(P, Decl(index.d.ts, 114, 13)) +>StatelessComponent : Symbol(StatelessComponent, Decl(index.d.ts, 114, 45)) +>P : Symbol(P, Decl(index.d.ts, 114, 13)) + + interface StatelessComponent

{ +>StatelessComponent : Symbol(StatelessComponent, Decl(index.d.ts, 114, 45)) +>P : Symbol(P, Decl(index.d.ts, 115, 33)) + + (props: P & { children?: ReactNode }, context?: any): ReactElement | null; +>props : Symbol(props, Decl(index.d.ts, 116, 9)) +>P : Symbol(P, Decl(index.d.ts, 115, 33)) +>children : Symbol(children, Decl(index.d.ts, 116, 21)) +>ReactNode : Symbol(ReactNode, Decl(index.d.ts, 121, 5)) +>context : Symbol(context, Decl(index.d.ts, 116, 45)) +>ReactElement : Symbol(ReactElement, Decl(index.d.ts, 79, 5)) + + propTypes?: ValidationMap

; +>propTypes : Symbol(StatelessComponent.propTypes, Decl(index.d.ts, 116, 87)) +>ValidationMap : Symbol(ValidationMap, Decl(index.d.ts, 136, 5)) +>P : Symbol(P, Decl(index.d.ts, 115, 33)) + + contextTypes?: ValidationMap; +>contextTypes : Symbol(StatelessComponent.contextTypes, Decl(index.d.ts, 117, 37)) +>ValidationMap : Symbol(ValidationMap, Decl(index.d.ts, 136, 5)) + + defaultProps?: Partial

; +>defaultProps : Symbol(StatelessComponent.defaultProps, Decl(index.d.ts, 118, 42)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>P : Symbol(P, Decl(index.d.ts, 115, 33)) + + displayName?: string; +>displayName : Symbol(StatelessComponent.displayName, Decl(index.d.ts, 119, 34)) + } + + type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; +>ReactNode : Symbol(ReactNode, Decl(index.d.ts, 121, 5)) +>ReactChild : Symbol(ReactChild, Decl(index.d.ts, 123, 77)) +>ReactFragment : Symbol(ReactFragment, Decl(index.d.ts, 125, 37)) + + type ReactChild = ReactElement | ReactText; +>ReactChild : Symbol(ReactChild, Decl(index.d.ts, 123, 77)) +>ReactElement : Symbol(ReactElement, Decl(index.d.ts, 79, 5)) +>ReactText : Symbol(ReactText, Decl(index.d.ts, 124, 52)) + + type ReactText = string | number; +>ReactText : Symbol(ReactText, Decl(index.d.ts, 124, 52)) + + // Should be Array but type aliases cannot be recursive + type ReactFragment = {} | Array; +>ReactFragment : Symbol(ReactFragment, Decl(index.d.ts, 125, 37)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>ReactChild : Symbol(ReactChild, Decl(index.d.ts, 123, 77)) + + interface ComponentClass

{ +>ComponentClass : Symbol(ComponentClass, Decl(index.d.ts, 127, 66)) +>P : Symbol(P, Decl(index.d.ts, 129, 29)) + + new (props?: P, context?: any): Component; +>props : Symbol(props, Decl(index.d.ts, 130, 13)) +>P : Symbol(P, Decl(index.d.ts, 129, 29)) +>context : Symbol(context, Decl(index.d.ts, 130, 23)) +>Component : Symbol(Component, Decl(index.d.ts, 62, 57)) +>P : Symbol(P, Decl(index.d.ts, 129, 29)) + + propTypes?: ValidationMap

; +>propTypes : Symbol(ComponentClass.propTypes, Decl(index.d.ts, 130, 57)) +>ValidationMap : Symbol(ValidationMap, Decl(index.d.ts, 136, 5)) +>P : Symbol(P, Decl(index.d.ts, 129, 29)) + + contextTypes?: ValidationMap; +>contextTypes : Symbol(ComponentClass.contextTypes, Decl(index.d.ts, 131, 37)) +>ValidationMap : Symbol(ValidationMap, Decl(index.d.ts, 136, 5)) + + childContextTypes?: ValidationMap; +>childContextTypes : Symbol(ComponentClass.childContextTypes, Decl(index.d.ts, 132, 42)) +>ValidationMap : Symbol(ValidationMap, Decl(index.d.ts, 136, 5)) + + defaultProps?: Partial

; +>defaultProps : Symbol(ComponentClass.defaultProps, Decl(index.d.ts, 133, 47)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>P : Symbol(P, Decl(index.d.ts, 129, 29)) + + displayName?: string; +>displayName : Symbol(ComponentClass.displayName, Decl(index.d.ts, 134, 34)) + } + + type ValidationMap = {[K in keyof T]?: Validator }; +>ValidationMap : Symbol(ValidationMap, Decl(index.d.ts, 136, 5)) +>T : Symbol(T, Decl(index.d.ts, 138, 23)) +>K : Symbol(K, Decl(index.d.ts, 138, 30)) +>T : Symbol(T, Decl(index.d.ts, 138, 23)) +>Validator : Symbol(Validator, Decl(index.d.ts, 138, 61)) +>T : Symbol(T, Decl(index.d.ts, 138, 23)) + + type Validator = (object: T, key: string, componentName: string, ...rest: any[]) => Error | null; +>Validator : Symbol(Validator, Decl(index.d.ts, 138, 61)) +>T : Symbol(T, Decl(index.d.ts, 139, 19)) +>object : Symbol(object, Decl(index.d.ts, 139, 25)) +>T : Symbol(T, Decl(index.d.ts, 139, 19)) +>key : Symbol(key, Decl(index.d.ts, 139, 35)) +>componentName : Symbol(componentName, Decl(index.d.ts, 139, 48)) +>rest : Symbol(rest, Decl(index.d.ts, 139, 71)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + function createElement

( +>createElement : Symbol(createElement, Decl(index.d.ts, 139, 104), Decl(index.d.ts, 144, 49), Decl(index.d.ts, 148, 84), Decl(index.d.ts, 152, 50)) +>P : Symbol(P, Decl(index.d.ts, 141, 27)) + + type: SFC

, +>type : Symbol(type, Decl(index.d.ts, 141, 30)) +>SFC : Symbol(SFC, Decl(index.d.ts, 112, 5)) +>P : Symbol(P, Decl(index.d.ts, 141, 27)) + + props?: Attributes & P, +>props : Symbol(props, Decl(index.d.ts, 142, 21)) +>Attributes : Symbol(Attributes, Decl(index.d.ts, 52, 84)) +>P : Symbol(P, Decl(index.d.ts, 141, 27)) + + ...children: ReactNode[]): SFCElement

; +>children : Symbol(children, Decl(index.d.ts, 143, 31)) +>ReactNode : Symbol(ReactNode, Decl(index.d.ts, 121, 5)) +>SFCElement : Symbol(SFCElement, Decl(index.d.ts, 85, 5)) +>P : Symbol(P, Decl(index.d.ts, 141, 27)) + + function createElement

( +>createElement : Symbol(createElement, Decl(index.d.ts, 139, 104), Decl(index.d.ts, 144, 49), Decl(index.d.ts, 148, 84), Decl(index.d.ts, 152, 50)) +>P : Symbol(P, Decl(index.d.ts, 145, 27)) + + type: ClassType, ClassicComponentClass

>, +>type : Symbol(type, Decl(index.d.ts, 145, 30)) +>ClassType : Symbol(ClassType, Decl(index.d.ts, 91, 29)) +>P : Symbol(P, Decl(index.d.ts, 145, 27)) +>ClassicComponent : Symbol(ClassicComponent, Decl(index.d.ts, 101, 5)) +>P : Symbol(P, Decl(index.d.ts, 145, 27)) +>ComponentState : Symbol(ComponentState, Decl(index.d.ts, 89, 5)) +>ClassicComponentClass : Symbol(ClassicComponentClass, Decl(index.d.ts, 107, 5)) +>P : Symbol(P, Decl(index.d.ts, 145, 27)) + + props?: ClassAttributes> & P, +>props : Symbol(props, Decl(index.d.ts, 146, 90)) +>ClassAttributes : Symbol(ClassAttributes, Decl(index.d.ts, 56, 5)) +>ClassicComponent : Symbol(ClassicComponent, Decl(index.d.ts, 101, 5)) +>P : Symbol(P, Decl(index.d.ts, 145, 27)) +>ComponentState : Symbol(ComponentState, Decl(index.d.ts, 89, 5)) +>P : Symbol(P, Decl(index.d.ts, 145, 27)) + + ...children: ReactNode[]): CElement>; +>children : Symbol(children, Decl(index.d.ts, 147, 73)) +>ReactNode : Symbol(ReactNode, Decl(index.d.ts, 121, 5)) +>CElement : Symbol(CElement, Decl(index.d.ts, 95, 59)) +>P : Symbol(P, Decl(index.d.ts, 145, 27)) +>ClassicComponent : Symbol(ClassicComponent, Decl(index.d.ts, 101, 5)) +>P : Symbol(P, Decl(index.d.ts, 145, 27)) +>ComponentState : Symbol(ComponentState, Decl(index.d.ts, 89, 5)) + + function createElement, C extends ComponentClass

>( +>createElement : Symbol(createElement, Decl(index.d.ts, 139, 104), Decl(index.d.ts, 144, 49), Decl(index.d.ts, 148, 84), Decl(index.d.ts, 152, 50)) +>P : Symbol(P, Decl(index.d.ts, 149, 27)) +>T : Symbol(T, Decl(index.d.ts, 149, 29)) +>Component : Symbol(Component, Decl(index.d.ts, 62, 57)) +>P : Symbol(P, Decl(index.d.ts, 149, 27)) +>ComponentState : Symbol(ComponentState, Decl(index.d.ts, 89, 5)) +>C : Symbol(C, Decl(index.d.ts, 149, 69)) +>ComponentClass : Symbol(ComponentClass, Decl(index.d.ts, 127, 66)) +>P : Symbol(P, Decl(index.d.ts, 149, 27)) + + type: ClassType, +>type : Symbol(type, Decl(index.d.ts, 149, 99)) +>ClassType : Symbol(ClassType, Decl(index.d.ts, 91, 29)) +>P : Symbol(P, Decl(index.d.ts, 149, 27)) +>T : Symbol(T, Decl(index.d.ts, 149, 29)) +>C : Symbol(C, Decl(index.d.ts, 149, 69)) + + props?: ClassAttributes & P, +>props : Symbol(props, Decl(index.d.ts, 150, 33)) +>ClassAttributes : Symbol(ClassAttributes, Decl(index.d.ts, 56, 5)) +>T : Symbol(T, Decl(index.d.ts, 149, 29)) +>P : Symbol(P, Decl(index.d.ts, 149, 27)) + + ...children: ReactNode[]): CElement; +>children : Symbol(children, Decl(index.d.ts, 151, 39)) +>ReactNode : Symbol(ReactNode, Decl(index.d.ts, 121, 5)) +>CElement : Symbol(CElement, Decl(index.d.ts, 95, 59)) +>P : Symbol(P, Decl(index.d.ts, 149, 27)) +>T : Symbol(T, Decl(index.d.ts, 149, 29)) + + function createElement

( +>createElement : Symbol(createElement, Decl(index.d.ts, 139, 104), Decl(index.d.ts, 144, 49), Decl(index.d.ts, 148, 84), Decl(index.d.ts, 152, 50)) +>P : Symbol(P, Decl(index.d.ts, 153, 27)) + + type: ComponentClass

, +>type : Symbol(type, Decl(index.d.ts, 153, 30)) +>ComponentClass : Symbol(ComponentClass, Decl(index.d.ts, 127, 66)) +>P : Symbol(P, Decl(index.d.ts, 153, 27)) + + props?: Attributes & P, +>props : Symbol(props, Decl(index.d.ts, 154, 32)) +>Attributes : Symbol(Attributes, Decl(index.d.ts, 52, 84)) +>P : Symbol(P, Decl(index.d.ts, 153, 27)) + + ...children: ReactNode[]): ReactElement

; +>children : Symbol(children, Decl(index.d.ts, 155, 31)) +>ReactNode : Symbol(ReactNode, Decl(index.d.ts, 121, 5)) +>ReactElement : Symbol(ReactElement, Decl(index.d.ts, 79, 5)) +>P : Symbol(P, Decl(index.d.ts, 153, 27)) +} + +declare global { +>global : Symbol(global, Decl(index.d.ts, 157, 1)) + + namespace JSX { +>JSX : Symbol(JSX, Decl(index.d.ts, 159, 16)) + + interface Element extends React.ReactElement {} +>Element : Symbol(Element, Decl(index.d.ts, 160, 19)) +>React.ReactElement : Symbol(React.ReactElement, Decl(index.d.ts, 79, 5)) +>React : Symbol(React, Decl(index.d.ts, 1, 15)) +>ReactElement : Symbol(React.ReactElement, Decl(index.d.ts, 79, 5)) + + interface ElementClass extends React.Component { +>ElementClass : Symbol(ElementClass, Decl(index.d.ts, 161, 60)) +>React.Component : Symbol(React.Component, Decl(index.d.ts, 62, 57)) +>React : Symbol(React, Decl(index.d.ts, 1, 15)) +>Component : Symbol(React.Component, Decl(index.d.ts, 62, 57)) + + render(): JSX.Element | null | false; +>render : Symbol(ElementClass.render, Decl(index.d.ts, 162, 61)) +>JSX : Symbol(JSX, Decl(index.d.ts, 159, 16)) +>Element : Symbol(Element, Decl(index.d.ts, 160, 19)) + } + interface ElementAttributesProperty { props: {}; } +>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(index.d.ts, 164, 9)) +>props : Symbol(ElementAttributesProperty.props, Decl(index.d.ts, 165, 45)) + + interface ElementChildrenAttribute { children: {}; } +>ElementChildrenAttribute : Symbol(ElementChildrenAttribute, Decl(index.d.ts, 165, 58)) +>children : Symbol(ElementChildrenAttribute.children, Decl(index.d.ts, 166, 44)) + + interface IntrinsicAttributes extends React.Attributes {} +>IntrinsicAttributes : Symbol(IntrinsicAttributes, Decl(index.d.ts, 166, 60)) +>React.Attributes : Symbol(React.Attributes, Decl(index.d.ts, 52, 84)) +>React : Symbol(React, Decl(index.d.ts, 1, 15)) +>Attributes : Symbol(React.Attributes, Decl(index.d.ts, 52, 84)) + + interface IntrinsicClassAttributes extends React.ClassAttributes {} +>IntrinsicClassAttributes : Symbol(IntrinsicClassAttributes, Decl(index.d.ts, 168, 65)) +>T : Symbol(T, Decl(index.d.ts, 169, 43)) +>React.ClassAttributes : Symbol(React.ClassAttributes, Decl(index.d.ts, 56, 5)) +>React : Symbol(React, Decl(index.d.ts, 1, 15)) +>ClassAttributes : Symbol(React.ClassAttributes, Decl(index.d.ts, 56, 5)) +>T : Symbol(T, Decl(index.d.ts, 169, 43)) + + interface IntrinsicElements { +>IntrinsicElements : Symbol(IntrinsicElements, Decl(index.d.ts, 169, 81)) + + input: React.DetailedHTMLProps, HTMLInputElement>; +>input : Symbol(IntrinsicElements.input, Decl(index.d.ts, 171, 37)) +>React : Symbol(React, Decl(index.d.ts, 1, 15)) +>DetailedHTMLProps : Symbol(React.DetailedHTMLProps, Decl(index.d.ts, 51, 74)) +>React : Symbol(React, Decl(index.d.ts, 1, 15)) +>InputHTMLAttributes : Symbol(React.InputHTMLAttributes, Decl(index.d.ts, 43, 59)) +>HTMLInputElement : Symbol(HTMLInputElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>HTMLInputElement : Symbol(HTMLInputElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + } + } +} + diff --git a/tests/baselines/reference/tsxRefInference.types b/tests/baselines/reference/tsxRefInference.types new file mode 100644 index 0000000000000..460bc91883c82 --- /dev/null +++ b/tests/baselines/reference/tsxRefInference.types @@ -0,0 +1,810 @@ +=== tests/cases/compiler/index.tsx === +import React = require("react"); +>React : typeof React + +interface MyInputProps extends React.DetailedHTMLProps, HTMLInputElement> { +>MyInputProps : MyInputProps +>React.DetailedHTMLProps : any +>React : typeof React +>DetailedHTMLProps : React.DetailedHTMLProps +>React : any +>InputHTMLAttributes : React.InputHTMLAttributes +>HTMLInputElement : HTMLInputElement +>HTMLInputElement : HTMLInputElement + + onValid?(): boolean; +>onValid : () => boolean + + onInvalid?(): boolean; +>onInvalid : () => boolean +} + +class MyInput implements React.Component { +>MyInput : MyInput +>React.Component : any +>React : typeof React +>Component : React.Component +>MyInputProps : MyInputProps + + props: MyInputProps; +>props : MyInputProps +>MyInputProps : MyInputProps + + render() { +>render : () => JSX.Element + + const { onValid, onInvalid, onChange, ...inputProps } = this.props; +>onValid : () => boolean +>onInvalid : () => boolean +>onChange : React.EventHandler> +>inputProps : { ref?: React.Ref; key?: string | number; onChangeCapture?: React.EventHandler>; onInput?: React.EventHandler>; onInputCapture?: React.EventHandler>; onReset?: React.EventHandler>; onResetCapture?: React.EventHandler>; onSubmit?: React.EventHandler>; onSubmitCapture?: React.EventHandler>; onInvalidCapture?: React.EventHandler>; } +>this.props : MyInputProps +>this : this +>props : MyInputProps + + return ( +>( ) : JSX.Element + + : JSX.Element +>input : any + + { ...inputProps } +>inputProps : { ref?: React.Ref; key?: string | number; onChangeCapture?: React.EventHandler>; onInput?: React.EventHandler>; onInputCapture?: React.EventHandler>; onReset?: React.EventHandler>; onResetCapture?: React.EventHandler>; onSubmit?: React.EventHandler>; onSubmitCapture?: React.EventHandler>; onInvalidCapture?: React.EventHandler>; } + + onChange={ this._onChange } +>onChange : (event: React.ChangeEvent) => void +>this._onChange : (event: React.ChangeEvent) => void +>this : this +>_onChange : (event: React.ChangeEvent) => void + + /> + ); + } + + componentDidMount() {} +>componentDidMount : () => void + + private _onChange(event: React.ChangeEvent) { +>_onChange : (event: React.ChangeEvent) => void +>event : React.ChangeEvent +>React : any +>ChangeEvent : React.ChangeEvent +>HTMLInputElement : HTMLInputElement + + // do some validation first... + + // ... then trigger onChange callback, if present: + if (this.props.onChange) { +>this.props.onChange : React.EventHandler> +>this.props : MyInputProps +>this : this +>props : MyInputProps +>onChange : React.EventHandler> + + this.props.onChange(event); +>this.props.onChange(event) : void +>this.props.onChange : React.EventHandler> +>this.props : MyInputProps +>this : this +>props : MyInputProps +>onChange : React.EventHandler> +>event : React.ChangeEvent + } + } +} + +function someFunction() {} +>someFunction : () => void + +const x = 0} onChange={someFunction} />; +>x : JSX.Element +> 0} onChange={someFunction} /> : JSX.Element +>MyInput : typeof MyInput +>ref : (r: HTMLInputElement | MyInput) => number +>r => 0 : (r: HTMLInputElement | MyInput) => number +>r : HTMLInputElement | MyInput +>0 : 0 +>onChange : () => void +>someFunction : () => void + +=== tests/cases/compiler/node_modules/react/index.d.ts === +export as namespace React; +>React : typeof React + +export = React; +>React : typeof React + +declare namespace React { +>React : typeof React + + interface SyntheticEvent { +>SyntheticEvent : SyntheticEvent +>T : T + + bubbles: boolean; +>bubbles : boolean + + currentTarget: EventTarget & T; +>currentTarget : EventTarget & T +>EventTarget : EventTarget +>T : T + + cancelable: boolean; +>cancelable : boolean + + defaultPrevented: boolean; +>defaultPrevented : boolean + + eventPhase: number; +>eventPhase : number + + isTrusted: boolean; +>isTrusted : boolean + + nativeEvent: Event; +>nativeEvent : Event +>Event : Event + + preventDefault(): void; +>preventDefault : () => void + + isDefaultPrevented(): boolean; +>isDefaultPrevented : () => boolean + + stopPropagation(): void; +>stopPropagation : () => void + + isPropagationStopped(): boolean; +>isPropagationStopped : () => boolean + + persist(): void; +>persist : () => void + + // If you thought this should be `EventTarget & T`, see https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12239 + target: EventTarget; +>target : EventTarget +>EventTarget : EventTarget + + timeStamp: number; +>timeStamp : number + + type: string; +>type : string + } + + interface ChangeEvent extends SyntheticEvent { +>ChangeEvent : ChangeEvent +>T : T +>SyntheticEvent : SyntheticEvent +>T : T + + target: EventTarget & T; +>target : EventTarget & T +>EventTarget : EventTarget +>T : T + } + + interface FormEvent extends SyntheticEvent { +>FormEvent : FormEvent +>T : T +>SyntheticEvent : SyntheticEvent +>T : T + } + + interface DOMAttributes { +>DOMAttributes : DOMAttributes +>T : T + + onChange?: FormEventHandler; +>onChange : (event: FormEvent) => void +>FormEventHandler : (event: FormEvent) => void +>T : T + + onChangeCapture?: FormEventHandler; +>onChangeCapture : (event: FormEvent) => void +>FormEventHandler : (event: FormEvent) => void +>T : T + + onInput?: FormEventHandler; +>onInput : (event: FormEvent) => void +>FormEventHandler : (event: FormEvent) => void +>T : T + + onInputCapture?: FormEventHandler; +>onInputCapture : (event: FormEvent) => void +>FormEventHandler : (event: FormEvent) => void +>T : T + + onReset?: FormEventHandler; +>onReset : (event: FormEvent) => void +>FormEventHandler : (event: FormEvent) => void +>T : T + + onResetCapture?: FormEventHandler; +>onResetCapture : (event: FormEvent) => void +>FormEventHandler : (event: FormEvent) => void +>T : T + + onSubmit?: FormEventHandler; +>onSubmit : (event: FormEvent) => void +>FormEventHandler : (event: FormEvent) => void +>T : T + + onSubmitCapture?: FormEventHandler; +>onSubmitCapture : (event: FormEvent) => void +>FormEventHandler : (event: FormEvent) => void +>T : T + + onInvalid?: FormEventHandler; +>onInvalid : (event: FormEvent) => void +>FormEventHandler : (event: FormEvent) => void +>T : T + + onInvalidCapture?: FormEventHandler; +>onInvalidCapture : (event: FormEvent) => void +>FormEventHandler : (event: FormEvent) => void +>T : T + } + + interface HTMLAttributes extends DOMAttributes {} +>HTMLAttributes : HTMLAttributes +>T : T +>DOMAttributes : DOMAttributes +>T : T + + interface InputHTMLAttributes extends HTMLAttributes { +>InputHTMLAttributes : InputHTMLAttributes +>T : T +>HTMLAttributes : HTMLAttributes +>T : T + + onChange?: ChangeEventHandler; +>onChange : (event: ChangeEvent) => void +>ChangeEventHandler : (event: ChangeEvent) => void +>T : T + } + + type FormEventHandler = EventHandler>; +>FormEventHandler : (event: FormEvent) => void +>T : T +>EventHandler : (event: E) => void +>FormEvent : FormEvent +>T : T + + type ChangeEventHandler = EventHandler>; +>ChangeEventHandler : (event: ChangeEvent) => void +>T : T +>EventHandler : (event: E) => void +>ChangeEvent : ChangeEvent +>T : T + + type EventHandler> = (event: E) => void; +>EventHandler : (event: E) => void +>E : E +>SyntheticEvent : SyntheticEvent +>event : E +>E : E + + type DetailedHTMLProps, T> = ClassAttributes & E; +>DetailedHTMLProps : ClassAttributes & E +>E : E +>HTMLAttributes : HTMLAttributes +>T : T +>T : T +>ClassAttributes : ClassAttributes +>T : T +>E : E + + interface Attributes { +>Attributes : Attributes + + key?: Key; +>key : string | number +>Key : string | number + } + interface ClassAttributes extends Attributes { +>ClassAttributes : ClassAttributes +>T : T +>Attributes : Attributes + + ref?: Ref; +>ref : string | ((instance: T) => any) +>Ref : string | ((instance: T) => any) +>T : T + } + + type Key = string | number; +>Key : string | number + + type Ref = string | ((instance: T | null) => any); +>Ref : string | ((instance: T) => any) +>T : T +>instance : T +>T : T +>null : null + + interface Component

extends ComponentLifecycle {} +>Component : Component +>P : P +>S : S +>ComponentLifecycle : ComponentLifecycle +>P : P +>S : S + + interface ComponentLifecycle { +>ComponentLifecycle : ComponentLifecycle +>P : P +>S : S + + componentWillMount?(): void; +>componentWillMount : () => void + + componentDidMount?(): void; +>componentDidMount : () => void + + componentWillReceiveProps?(nextProps: Readonly

, nextContext: any): void; +>componentWillReceiveProps : (nextProps: Readonly

, nextContext: any) => void +>nextProps : Readonly

+>Readonly : Readonly +>P : P +>nextContext : any + + shouldComponentUpdate?(nextProps: Readonly

, nextState: Readonly, nextContext: any): boolean; +>shouldComponentUpdate : (nextProps: Readonly

, nextState: Readonly, nextContext: any) => boolean +>nextProps : Readonly

+>Readonly : Readonly +>P : P +>nextState : Readonly +>Readonly : Readonly +>S : S +>nextContext : any + + componentWillUpdate?(nextProps: Readonly

, nextState: Readonly, nextContext: any): void; +>componentWillUpdate : (nextProps: Readonly

, nextState: Readonly, nextContext: any) => void +>nextProps : Readonly

+>Readonly : Readonly +>P : P +>nextState : Readonly +>Readonly : Readonly +>S : S +>nextContext : any + + componentDidUpdate?(prevProps: Readonly

, prevState: Readonly, prevContext: any): void; +>componentDidUpdate : (prevProps: Readonly

, prevState: Readonly, prevContext: any) => void +>prevProps : Readonly

+>Readonly : Readonly +>P : P +>prevState : Readonly +>Readonly : Readonly +>S : S +>prevContext : any + + componentWillUnmount?(): void; +>componentWillUnmount : () => void + + componentDidCatch?(error: Error, errorInfo: ErrorInfo): void; +>componentDidCatch : (error: Error, errorInfo: ErrorInfo) => void +>error : Error +>Error : Error +>errorInfo : ErrorInfo +>ErrorInfo : ErrorInfo + } + + interface ErrorInfo { +>ErrorInfo : ErrorInfo + + componentStack: string; +>componentStack : string + } + + interface ReactElement

{ +>ReactElement : ReactElement

+>P : P + + type: string | ComponentClass

| SFC

; +>type : string | ComponentClass

| StatelessComponent

+>ComponentClass : ComponentClass

+>P : P +>SFC : StatelessComponent

+>P : P + + props: P; +>props : P +>P : P + + key: Key | null; +>key : string | number +>Key : string | number +>null : null + } + + interface SFCElement

extends ReactElement

{ +>SFCElement : SFCElement

+>P : P +>ReactElement : ReactElement

+>P : P + + type: SFC

; +>type : StatelessComponent

+>SFC : StatelessComponent

+>P : P + } + + type ComponentState = {}; +>ComponentState : {} + + type ClassType, C extends ComponentClass

> = +>ClassType : C & (new (props?: P, context?: any) => T) & (new (props?: P, context?: any) => { props: P; }) +>P : P +>T : T +>Component : Component +>P : P +>ComponentState : {} +>C : C +>ComponentClass : ComponentClass

+>P : P + + & C +>C : C + + & (new (props?: P, context?: any) => T) +>props : P +>P : P +>context : any +>T : T + + & (new (props?: P, context?: any) => { props: P }); +>props : P +>P : P +>context : any +>props : P +>P : P + + type CElement> = ComponentElement; +>CElement : ComponentElement +>P : P +>T : T +>Component : Component +>P : P +>ComponentState : {} +>ComponentElement : ComponentElement +>P : P +>T : T + + interface ComponentElement> extends ReactElement

{ +>ComponentElement : ComponentElement +>P : P +>T : T +>Component : Component +>P : P +>ComponentState : {} +>ReactElement : ReactElement

+>P : P + + type: ComponentClass

; +>type : ComponentClass

+>ComponentClass : ComponentClass

+>P : P + + ref?: Ref; +>ref : string | ((instance: T) => any) +>Ref : string | ((instance: T) => any) +>T : T + } + + interface ClassicComponent

extends Component { +>ClassicComponent : ClassicComponent +>P : P +>S : S +>Component : Component +>P : P +>S : S + + replaceState(nextState: S, callback?: () => any): void; +>replaceState : (nextState: S, callback?: () => any) => void +>nextState : S +>S : S +>callback : () => any + + isMounted(): boolean; +>isMounted : () => boolean + + getInitialState?(): S; +>getInitialState : () => S +>S : S + } + + interface ClassicComponentClass

extends ComponentClass

{ +>ClassicComponentClass : ClassicComponentClass

+>P : P +>ComponentClass : ComponentClass

+>P : P + + new (props?: P, context?: any): ClassicComponent; +>props : P +>P : P +>context : any +>ClassicComponent : ClassicComponent +>P : P +>ComponentState : {} + + getDefaultProps?(): P; +>getDefaultProps : () => P +>P : P + } + + type SFC

= StatelessComponent

; +>SFC : StatelessComponent

+>P : P +>StatelessComponent : StatelessComponent

+>P : P + + interface StatelessComponent

{ +>StatelessComponent : StatelessComponent

+>P : P + + (props: P & { children?: ReactNode }, context?: any): ReactElement | null; +>props : P & { children?: string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[]; } +>P : P +>children : string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[] +>ReactNode : string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[] +>context : any +>ReactElement : ReactElement

+>null : null + + propTypes?: ValidationMap

; +>propTypes : { [K in keyof T]?: (object: P, key: string, componentName: string, ...rest: any[]) => Error; } +>ValidationMap : { [K in keyof T]?: (object: T, key: string, componentName: string, ...rest: any[]) => Error; } +>P : P + + contextTypes?: ValidationMap; +>contextTypes : any +>ValidationMap : { [K in keyof T]?: (object: T, key: string, componentName: string, ...rest: any[]) => Error; } + + defaultProps?: Partial

; +>defaultProps : Partial

+>Partial : Partial +>P : P + + displayName?: string; +>displayName : string + } + + type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; +>ReactNode : string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[] +>ReactChild : string | number | ReactElement +>ReactFragment : {} | (string | number | boolean | any[] | ReactElement)[] +>null : null + + type ReactChild = ReactElement | ReactText; +>ReactChild : string | number | ReactElement +>ReactElement : ReactElement

+>ReactText : string | number + + type ReactText = string | number; +>ReactText : string | number + + // Should be Array but type aliases cannot be recursive + type ReactFragment = {} | Array; +>ReactFragment : {} | (string | number | boolean | any[] | ReactElement)[] +>Array : T[] +>ReactChild : string | number | ReactElement + + interface ComponentClass

{ +>ComponentClass : ComponentClass

+>P : P + + new (props?: P, context?: any): Component; +>props : P +>P : P +>context : any +>Component : Component +>P : P + + propTypes?: ValidationMap

; +>propTypes : { [K in keyof T]?: (object: P, key: string, componentName: string, ...rest: any[]) => Error; } +>ValidationMap : { [K in keyof T]?: (object: T, key: string, componentName: string, ...rest: any[]) => Error; } +>P : P + + contextTypes?: ValidationMap; +>contextTypes : any +>ValidationMap : { [K in keyof T]?: (object: T, key: string, componentName: string, ...rest: any[]) => Error; } + + childContextTypes?: ValidationMap; +>childContextTypes : any +>ValidationMap : { [K in keyof T]?: (object: T, key: string, componentName: string, ...rest: any[]) => Error; } + + defaultProps?: Partial

; +>defaultProps : Partial

+>Partial : Partial +>P : P + + displayName?: string; +>displayName : string + } + + type ValidationMap = {[K in keyof T]?: Validator }; +>ValidationMap : { [K in keyof T]?: (object: T, key: string, componentName: string, ...rest: any[]) => Error; } +>T : T +>K : K +>T : T +>Validator : (object: T, key: string, componentName: string, ...rest: any[]) => Error +>T : T + + type Validator = (object: T, key: string, componentName: string, ...rest: any[]) => Error | null; +>Validator : (object: T, key: string, componentName: string, ...rest: any[]) => Error +>T : T +>object : T +>T : T +>key : string +>componentName : string +>rest : any[] +>Error : Error +>null : null + + function createElement

( +>createElement : {

(type: StatelessComponent

, props?: Attributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): SFCElement

;

(type: ClassicComponentClass

& (new (props?: P, context?: any) => ClassicComponent) & (new (props?: P, context?: any) => { props: P; }), props?: ClassAttributes> & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ComponentElement>; , C extends ComponentClass

>(type: C & (new (props?: P, context?: any) => T) & (new (props?: P, context?: any) => { props: P; }), props?: ClassAttributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ComponentElement;

(type: ComponentClass

, props?: Attributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ReactElement

; } +>P : P + + type: SFC

, +>type : StatelessComponent

+>SFC : StatelessComponent

+>P : P + + props?: Attributes & P, +>props : Attributes & P +>Attributes : Attributes +>P : P + + ...children: ReactNode[]): SFCElement

; +>children : (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[] +>ReactNode : string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[] +>SFCElement : SFCElement

+>P : P + + function createElement

( +>createElement : {

(type: StatelessComponent

, props?: Attributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): SFCElement

;

(type: ClassicComponentClass

& (new (props?: P, context?: any) => ClassicComponent) & (new (props?: P, context?: any) => { props: P; }), props?: ClassAttributes> & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ComponentElement>; , C extends ComponentClass

>(type: C & (new (props?: P, context?: any) => T) & (new (props?: P, context?: any) => { props: P; }), props?: ClassAttributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ComponentElement;

(type: ComponentClass

, props?: Attributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ReactElement

; } +>P : P + + type: ClassType, ClassicComponentClass

>, +>type : ClassicComponentClass

& (new (props?: P, context?: any) => ClassicComponent) & (new (props?: P, context?: any) => { props: P; }) +>ClassType : C & (new (props?: P, context?: any) => T) & (new (props?: P, context?: any) => { props: P; }) +>P : P +>ClassicComponent : ClassicComponent +>P : P +>ComponentState : {} +>ClassicComponentClass : ClassicComponentClass

+>P : P + + props?: ClassAttributes> & P, +>props : ClassAttributes> & P +>ClassAttributes : ClassAttributes +>ClassicComponent : ClassicComponent +>P : P +>ComponentState : {} +>P : P + + ...children: ReactNode[]): CElement>; +>children : (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[] +>ReactNode : string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[] +>CElement : ComponentElement +>P : P +>ClassicComponent : ClassicComponent +>P : P +>ComponentState : {} + + function createElement, C extends ComponentClass

>( +>createElement : {

(type: StatelessComponent

, props?: Attributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): SFCElement

;

(type: ClassicComponentClass

& (new (props?: P, context?: any) => ClassicComponent) & (new (props?: P, context?: any) => { props: P; }), props?: ClassAttributes> & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ComponentElement>; , C extends ComponentClass

>(type: C & (new (props?: P, context?: any) => T) & (new (props?: P, context?: any) => { props: P; }), props?: ClassAttributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ComponentElement;

(type: ComponentClass

, props?: Attributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ReactElement

; } +>P : P +>T : T +>Component : Component +>P : P +>ComponentState : {} +>C : C +>ComponentClass : ComponentClass

+>P : P + + type: ClassType, +>type : C & (new (props?: P, context?: any) => T) & (new (props?: P, context?: any) => { props: P; }) +>ClassType : C & (new (props?: P, context?: any) => T) & (new (props?: P, context?: any) => { props: P; }) +>P : P +>T : T +>C : C + + props?: ClassAttributes & P, +>props : ClassAttributes & P +>ClassAttributes : ClassAttributes +>T : T +>P : P + + ...children: ReactNode[]): CElement; +>children : (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[] +>ReactNode : string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[] +>CElement : ComponentElement +>P : P +>T : T + + function createElement

( +>createElement : {

(type: StatelessComponent

, props?: Attributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): SFCElement

;

(type: ClassicComponentClass

& (new (props?: P, context?: any) => ClassicComponent) & (new (props?: P, context?: any) => { props: P; }), props?: ClassAttributes> & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ComponentElement>; , C extends ComponentClass

>(type: C & (new (props?: P, context?: any) => T) & (new (props?: P, context?: any) => { props: P; }), props?: ClassAttributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ComponentElement;

(type: ComponentClass

, props?: Attributes & P, ...children: (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[]): ReactElement

; } +>P : P + + type: ComponentClass

, +>type : ComponentClass

+>ComponentClass : ComponentClass

+>P : P + + props?: Attributes & P, +>props : Attributes & P +>Attributes : Attributes +>P : P + + ...children: ReactNode[]): ReactElement

; +>children : (string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[])[] +>ReactNode : string | number | boolean | {} | ReactElement | (string | number | boolean | any[] | ReactElement)[] +>ReactElement : ReactElement

+>P : P +} + +declare global { +>global : any + + namespace JSX { +>JSX : any + + interface Element extends React.ReactElement {} +>Element : Element +>React.ReactElement : any +>React : typeof React +>ReactElement : React.ReactElement

+ + interface ElementClass extends React.Component { +>ElementClass : ElementClass +>React.Component : any +>React : typeof React +>Component : React.Component + + render(): JSX.Element | null | false; +>render : () => false | Element +>JSX : any +>Element : Element +>null : null +>false : false + } + interface ElementAttributesProperty { props: {}; } +>ElementAttributesProperty : ElementAttributesProperty +>props : {} + + interface ElementChildrenAttribute { children: {}; } +>ElementChildrenAttribute : ElementChildrenAttribute +>children : {} + + interface IntrinsicAttributes extends React.Attributes {} +>IntrinsicAttributes : IntrinsicAttributes +>React.Attributes : any +>React : typeof React +>Attributes : React.Attributes + + interface IntrinsicClassAttributes extends React.ClassAttributes {} +>IntrinsicClassAttributes : IntrinsicClassAttributes +>T : T +>React.ClassAttributes : any +>React : typeof React +>ClassAttributes : React.ClassAttributes +>T : T + + interface IntrinsicElements { +>IntrinsicElements : IntrinsicElements + + input: React.DetailedHTMLProps, HTMLInputElement>; +>input : React.ClassAttributes & React.InputHTMLAttributes +>React : any +>DetailedHTMLProps : React.ClassAttributes & E +>React : any +>InputHTMLAttributes : React.InputHTMLAttributes +>HTMLInputElement : HTMLInputElement +>HTMLInputElement : HTMLInputElement + } + } +} + diff --git a/tests/cases/compiler/tsxRefInference.tsx b/tests/cases/compiler/tsxRefInference.tsx new file mode 100644 index 0000000000000..44d5f662dc4b8 --- /dev/null +++ b/tests/cases/compiler/tsxRefInference.tsx @@ -0,0 +1,216 @@ +// @jsx: react +// @moduleResolution: node +// @noImplicitAny: true +// @lib: dom,es6 +// @filename: node_modules/react/index.d.ts +export as namespace React; +export = React; + +declare namespace React { + interface SyntheticEvent { + bubbles: boolean; + currentTarget: EventTarget & T; + cancelable: boolean; + defaultPrevented: boolean; + eventPhase: number; + isTrusted: boolean; + nativeEvent: Event; + preventDefault(): void; + isDefaultPrevented(): boolean; + stopPropagation(): void; + isPropagationStopped(): boolean; + persist(): void; + // If you thought this should be `EventTarget & T`, see https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12239 + target: EventTarget; + timeStamp: number; + type: string; + } + + interface ChangeEvent extends SyntheticEvent { + target: EventTarget & T; + } + + interface FormEvent extends SyntheticEvent { + } + + interface DOMAttributes { + onChange?: FormEventHandler; + onChangeCapture?: FormEventHandler; + onInput?: FormEventHandler; + onInputCapture?: FormEventHandler; + onReset?: FormEventHandler; + onResetCapture?: FormEventHandler; + onSubmit?: FormEventHandler; + onSubmitCapture?: FormEventHandler; + onInvalid?: FormEventHandler; + onInvalidCapture?: FormEventHandler; + } + + interface HTMLAttributes extends DOMAttributes {} + + interface InputHTMLAttributes extends HTMLAttributes { + onChange?: ChangeEventHandler; + } + + type FormEventHandler = EventHandler>; + type ChangeEventHandler = EventHandler>; + type EventHandler> = (event: E) => void; + type DetailedHTMLProps, T> = ClassAttributes & E; + + interface Attributes { + key?: Key; + } + interface ClassAttributes extends Attributes { + ref?: Ref; + } + + type Key = string | number; + type Ref = string | ((instance: T | null) => any); + + interface Component

extends ComponentLifecycle {} + + interface ComponentLifecycle { + componentWillMount?(): void; + componentDidMount?(): void; + componentWillReceiveProps?(nextProps: Readonly

, nextContext: any): void; + shouldComponentUpdate?(nextProps: Readonly

, nextState: Readonly, nextContext: any): boolean; + componentWillUpdate?(nextProps: Readonly

, nextState: Readonly, nextContext: any): void; + componentDidUpdate?(prevProps: Readonly

, prevState: Readonly, prevContext: any): void; + componentWillUnmount?(): void; + componentDidCatch?(error: Error, errorInfo: ErrorInfo): void; + } + + interface ErrorInfo { + componentStack: string; + } + + interface ReactElement

{ + type: string | ComponentClass

| SFC

; + props: P; + key: Key | null; + } + + interface SFCElement

extends ReactElement

{ + type: SFC

; + } + + type ComponentState = {}; + type ClassType, C extends ComponentClass

> = + & C + & (new (props?: P, context?: any) => T) + & (new (props?: P, context?: any) => { props: P }); + + type CElement> = ComponentElement; + interface ComponentElement> extends ReactElement

{ + type: ComponentClass

; + ref?: Ref; + } + + interface ClassicComponent

extends Component { + replaceState(nextState: S, callback?: () => any): void; + isMounted(): boolean; + getInitialState?(): S; + } + + interface ClassicComponentClass

extends ComponentClass

{ + new (props?: P, context?: any): ClassicComponent; + getDefaultProps?(): P; + } + + type SFC

= StatelessComponent

; + interface StatelessComponent

{ + (props: P & { children?: ReactNode }, context?: any): ReactElement | null; + propTypes?: ValidationMap

; + contextTypes?: ValidationMap; + defaultProps?: Partial

; + displayName?: string; + } + + type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; + type ReactChild = ReactElement | ReactText; + type ReactText = string | number; + // Should be Array but type aliases cannot be recursive + type ReactFragment = {} | Array; + + interface ComponentClass

{ + new (props?: P, context?: any): Component; + propTypes?: ValidationMap

; + contextTypes?: ValidationMap; + childContextTypes?: ValidationMap; + defaultProps?: Partial

; + displayName?: string; + } + + type ValidationMap = {[K in keyof T]?: Validator }; + type Validator = (object: T, key: string, componentName: string, ...rest: any[]) => Error | null; + + function createElement

( + type: SFC

, + props?: Attributes & P, + ...children: ReactNode[]): SFCElement

; + function createElement

( + type: ClassType, ClassicComponentClass

>, + props?: ClassAttributes> & P, + ...children: ReactNode[]): CElement>; + function createElement, C extends ComponentClass

>( + type: ClassType, + props?: ClassAttributes & P, + ...children: ReactNode[]): CElement; + function createElement

( + type: ComponentClass

, + props?: Attributes & P, + ...children: ReactNode[]): ReactElement

; +} + +declare global { + namespace JSX { + interface Element extends React.ReactElement {} + interface ElementClass extends React.Component { + render(): JSX.Element | null | false; + } + interface ElementAttributesProperty { props: {}; } + interface ElementChildrenAttribute { children: {}; } + + interface IntrinsicAttributes extends React.Attributes {} + interface IntrinsicClassAttributes extends React.ClassAttributes {} + + interface IntrinsicElements { + input: React.DetailedHTMLProps, HTMLInputElement>; + } + } +} + +// @filename: index.tsx +import React = require("react"); + +interface MyInputProps extends React.DetailedHTMLProps, HTMLInputElement> { + onValid?(): boolean; + onInvalid?(): boolean; +} + +class MyInput implements React.Component { + props: MyInputProps; + render() { + const { onValid, onInvalid, onChange, ...inputProps } = this.props; + return ( + + ); + } + + componentDidMount() {} + + private _onChange(event: React.ChangeEvent) { + // do some validation first... + + // ... then trigger onChange callback, if present: + if (this.props.onChange) { + this.props.onChange(event); + } + } +} + +function someFunction() {} +const x = 0} onChange={someFunction} />; \ No newline at end of file