diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8fa3c4fce2a4a..977c5b641e8c1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -24603,9 +24603,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (relation === identityRelation) { return signaturesIdenticalTo(source, target, kind); } - if (target === anyFunctionType || source === anyFunctionType) { + // With respect to signatures, the anyFunctionType wildcard is a subtype of every other function type. + if (source === anyFunctionType) { return Ternary.True; } + if (target === anyFunctionType) { + return Ternary.False; + } const sourceIsJSConstructor = source.symbol && isJSConstructor(source.symbol.valueDeclaration); const targetIsJSConstructor = target.symbol && isJSConstructor(target.symbol.valueDeclaration); @@ -33925,7 +33929,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { childrenPropSymbol.valueDeclaration.symbol = childrenPropSymbol; const childPropMap = createSymbolTable(); childPropMap.set(jsxChildrenPropertyName, childrenPropSymbol); - spread = getSpreadType(spread, createAnonymousType(attributesSymbol, childPropMap, emptyArray, emptyArray, emptyArray), attributesSymbol, objectFlags, /*readonly*/ false); + spread = getSpreadType(spread, createAnonymousType(attributesSymbol, childPropMap, emptyArray, emptyArray, emptyArray), attributesSymbol, objectFlags | getPropagatingFlagsOfTypes(childrenTypes), /*readonly*/ false); } } diff --git a/tests/baselines/reference/contextuallyTypedJsxChildren2.symbols b/tests/baselines/reference/contextuallyTypedJsxChildren2.symbols new file mode 100644 index 0000000000000..a1afef7c59eb0 --- /dev/null +++ b/tests/baselines/reference/contextuallyTypedJsxChildren2.symbols @@ -0,0 +1,186 @@ +//// [tests/cases/compiler/contextuallyTypedJsxChildren2.tsx] //// + +=== contextuallyTypedJsxChildren2.tsx === +/// + +// https://github.com/microsoft/typescript-go/issues/2802 + +import * as React from 'react'; +>React : Symbol(React, Decl(contextuallyTypedJsxChildren2.tsx, 4, 6)) + +declare const TestComponentWithChildren: (props: { +>TestComponentWithChildren : Symbol(TestComponentWithChildren, Decl(contextuallyTypedJsxChildren2.tsx, 6, 13)) +>T : Symbol(T, Decl(contextuallyTypedJsxChildren2.tsx, 6, 42)) +>TParam : Symbol(TParam, Decl(contextuallyTypedJsxChildren2.tsx, 6, 44)) +>props : Symbol(props, Decl(contextuallyTypedJsxChildren2.tsx, 6, 53)) + + state: T; +>state : Symbol(state, Decl(contextuallyTypedJsxChildren2.tsx, 6, 61)) +>T : Symbol(T, Decl(contextuallyTypedJsxChildren2.tsx, 6, 42)) + + selector?: (state: NoInfer) => TParam; +>selector : Symbol(selector, Decl(contextuallyTypedJsxChildren2.tsx, 7, 11)) +>state : Symbol(state, Decl(contextuallyTypedJsxChildren2.tsx, 8, 14)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(contextuallyTypedJsxChildren2.tsx, 6, 42)) +>TParam : Symbol(TParam, Decl(contextuallyTypedJsxChildren2.tsx, 6, 44)) + + children?: (state: NoInfer) => React.ReactElement | null; +>children : Symbol(children, Decl(contextuallyTypedJsxChildren2.tsx, 8, 43)) +>state : Symbol(state, Decl(contextuallyTypedJsxChildren2.tsx, 9, 14)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>TParam : Symbol(TParam, Decl(contextuallyTypedJsxChildren2.tsx, 6, 44)) +>React : Symbol(React, Decl(contextuallyTypedJsxChildren2.tsx, 4, 6)) +>ReactElement : Symbol(React.ReactElement, Decl(react16.d.ts, 135, 9)) + +}) => React.ReactElement; +>React : Symbol(React, Decl(contextuallyTypedJsxChildren2.tsx, 4, 6)) +>ReactElement : Symbol(React.ReactElement, Decl(react16.d.ts, 135, 9)) + +declare const TestComponentWithoutChildren: (props: { +>TestComponentWithoutChildren : Symbol(TestComponentWithoutChildren, Decl(contextuallyTypedJsxChildren2.tsx, 12, 13)) +>T : Symbol(T, Decl(contextuallyTypedJsxChildren2.tsx, 12, 45)) +>TParam : Symbol(TParam, Decl(contextuallyTypedJsxChildren2.tsx, 12, 47)) +>props : Symbol(props, Decl(contextuallyTypedJsxChildren2.tsx, 12, 56)) + + state: T; +>state : Symbol(state, Decl(contextuallyTypedJsxChildren2.tsx, 12, 64)) +>T : Symbol(T, Decl(contextuallyTypedJsxChildren2.tsx, 12, 45)) + + selector?: (state: NoInfer) => TParam; +>selector : Symbol(selector, Decl(contextuallyTypedJsxChildren2.tsx, 13, 11)) +>state : Symbol(state, Decl(contextuallyTypedJsxChildren2.tsx, 14, 14)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(contextuallyTypedJsxChildren2.tsx, 12, 45)) +>TParam : Symbol(TParam, Decl(contextuallyTypedJsxChildren2.tsx, 12, 47)) + + notChildren?: (state: NoInfer) => React.ReactElement | null; +>notChildren : Symbol(notChildren, Decl(contextuallyTypedJsxChildren2.tsx, 14, 43)) +>state : Symbol(state, Decl(contextuallyTypedJsxChildren2.tsx, 15, 17)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>TParam : Symbol(TParam, Decl(contextuallyTypedJsxChildren2.tsx, 12, 47)) +>React : Symbol(React, Decl(contextuallyTypedJsxChildren2.tsx, 4, 6)) +>ReactElement : Symbol(React.ReactElement, Decl(react16.d.ts, 135, 9)) + +}) => React.ReactElement; +>React : Symbol(React, Decl(contextuallyTypedJsxChildren2.tsx, 4, 6)) +>ReactElement : Symbol(React.ReactElement, Decl(react16.d.ts, 135, 9)) + +const App = () => { +>App : Symbol(App, Decl(contextuallyTypedJsxChildren2.tsx, 18, 5)) + + return ( + <> + state.foo}> +>TestComponentWithChildren : Symbol(TestComponentWithChildren, Decl(contextuallyTypedJsxChildren2.tsx, 6, 13)) +>state : Symbol(state, Decl(contextuallyTypedJsxChildren2.tsx, 21, 32)) +>foo : Symbol(foo, Decl(contextuallyTypedJsxChildren2.tsx, 21, 41)) +>selector : Symbol(selector, Decl(contextuallyTypedJsxChildren2.tsx, 21, 53)) +>state : Symbol(state, Decl(contextuallyTypedJsxChildren2.tsx, 21, 65)) +>state.foo : Symbol(foo, Decl(contextuallyTypedJsxChildren2.tsx, 21, 41)) +>state : Symbol(state, Decl(contextuallyTypedJsxChildren2.tsx, 21, 65)) +>foo : Symbol(foo, Decl(contextuallyTypedJsxChildren2.tsx, 21, 41)) + + {(selected) =>
{Math.max(selected, 0)}
} +>selected : Symbol(selected, Decl(contextuallyTypedJsxChildren2.tsx, 22, 10)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2548, 114)) +>Math.max : Symbol(Math.max, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>max : Symbol(Math.max, Decl(lib.es5.d.ts, --, --)) +>selected : Symbol(selected, Decl(contextuallyTypedJsxChildren2.tsx, 22, 10)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2548, 114)) + +
+>TestComponentWithChildren : Symbol(TestComponentWithChildren, Decl(contextuallyTypedJsxChildren2.tsx, 6, 13)) + + TestComponentWithoutChildren : Symbol(TestComponentWithoutChildren, Decl(contextuallyTypedJsxChildren2.tsx, 12, 13)) + + state={{ foo: 123 }} +>state : Symbol(state, Decl(contextuallyTypedJsxChildren2.tsx, 25, 35)) +>foo : Symbol(foo, Decl(contextuallyTypedJsxChildren2.tsx, 26, 16)) + + selector={(state) => state.foo} +>selector : Symbol(selector, Decl(contextuallyTypedJsxChildren2.tsx, 26, 28)) +>state : Symbol(state, Decl(contextuallyTypedJsxChildren2.tsx, 27, 19)) +>state.foo : Symbol(foo, Decl(contextuallyTypedJsxChildren2.tsx, 26, 16)) +>state : Symbol(state, Decl(contextuallyTypedJsxChildren2.tsx, 27, 19)) +>foo : Symbol(foo, Decl(contextuallyTypedJsxChildren2.tsx, 26, 16)) + + notChildren={(selected) =>
{Math.max(selected, 0)}
} +>notChildren : Symbol(notChildren, Decl(contextuallyTypedJsxChildren2.tsx, 27, 39)) +>selected : Symbol(selected, Decl(contextuallyTypedJsxChildren2.tsx, 28, 22)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2548, 114)) +>Math.max : Symbol(Math.max, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>max : Symbol(Math.max, Decl(lib.es5.d.ts, --, --)) +>selected : Symbol(selected, Decl(contextuallyTypedJsxChildren2.tsx, 28, 22)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2548, 114)) + + /> + + ); +}; + +// https://github.com/microsoft/typescript-go/issues/2797 + +interface State { +>State : Symbol(State, Decl(contextuallyTypedJsxChildren2.tsx, 32, 2)) + + value: boolean +>value : Symbol(State.value, Decl(contextuallyTypedJsxChildren2.tsx, 36, 17)) +} + +declare const Subscribe: (props: { +>Subscribe : Symbol(Subscribe, Decl(contextuallyTypedJsxChildren2.tsx, 40, 13)) +>TSelected : Symbol(TSelected, Decl(contextuallyTypedJsxChildren2.tsx, 40, 26)) +>State : Symbol(State, Decl(contextuallyTypedJsxChildren2.tsx, 32, 2)) +>props : Symbol(props, Decl(contextuallyTypedJsxChildren2.tsx, 40, 45)) + + selector?: (state: State) => TSelected +>selector : Symbol(selector, Decl(contextuallyTypedJsxChildren2.tsx, 40, 53)) +>state : Symbol(state, Decl(contextuallyTypedJsxChildren2.tsx, 41, 14)) +>State : Symbol(State, Decl(contextuallyTypedJsxChildren2.tsx, 32, 2)) +>TSelected : Symbol(TSelected, Decl(contextuallyTypedJsxChildren2.tsx, 40, 26)) + + children: (state: TSelected) => void +>children : Symbol(children, Decl(contextuallyTypedJsxChildren2.tsx, 41, 40)) +>state : Symbol(state, Decl(contextuallyTypedJsxChildren2.tsx, 42, 13)) +>TSelected : Symbol(TSelected, Decl(contextuallyTypedJsxChildren2.tsx, 40, 26)) + +}) => React.ReactElement +>React : Symbol(React, Decl(contextuallyTypedJsxChildren2.tsx, 4, 6)) +>ReactElement : Symbol(React.ReactElement, Decl(react16.d.ts, 135, 9)) + +const _result = ( +>_result : Symbol(_result, Decl(contextuallyTypedJsxChildren2.tsx, 45, 5)) + + Subscribe : Symbol(Subscribe, Decl(contextuallyTypedJsxChildren2.tsx, 40, 13)) + + selector={(state) => { +>selector : Symbol(selector, Decl(contextuallyTypedJsxChildren2.tsx, 46, 12)) +>state : Symbol(state, Decl(contextuallyTypedJsxChildren2.tsx, 47, 15)) + + return [state.value] +>state.value : Symbol(State.value, Decl(contextuallyTypedJsxChildren2.tsx, 36, 17)) +>state : Symbol(state, Decl(contextuallyTypedJsxChildren2.tsx, 47, 15)) +>value : Symbol(State.value, Decl(contextuallyTypedJsxChildren2.tsx, 36, 17)) + + }} + > + {([value = false]) => { +>value : Symbol(value, Decl(contextuallyTypedJsxChildren2.tsx, 51, 7)) + + console.log(value) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>value : Symbol(value, Decl(contextuallyTypedJsxChildren2.tsx, 51, 7)) + + }} + +>Subscribe : Symbol(Subscribe, Decl(contextuallyTypedJsxChildren2.tsx, 40, 13)) + +) + diff --git a/tests/baselines/reference/contextuallyTypedJsxChildren2.types b/tests/baselines/reference/contextuallyTypedJsxChildren2.types new file mode 100644 index 0000000000000..096577cec0dab --- /dev/null +++ b/tests/baselines/reference/contextuallyTypedJsxChildren2.types @@ -0,0 +1,291 @@ +//// [tests/cases/compiler/contextuallyTypedJsxChildren2.tsx] //// + +=== Performance Stats === +Assignability cache: 2,500 +Type Count: 10,000 +Instantiation count: 100,000 +Symbol count: 50,000 + +=== contextuallyTypedJsxChildren2.tsx === +/// + +// https://github.com/microsoft/typescript-go/issues/2802 + +import * as React from 'react'; +>React : typeof React +> : ^^^^^^^^^^^^ + +declare const TestComponentWithChildren: (props: { +>TestComponentWithChildren : (props: { state: T; selector?: (state: NoInfer) => TParam; children?: (state: NoInfer) => React.ReactElement | null; }) => React.ReactElement +> : ^ ^^ ^^ ^^ ^^^^^ +>props : { state: T; selector?: (state: NoInfer) => TParam; children?: (state: NoInfer) => React.ReactElement | null; } +> : ^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^ + + state: T; +>state : T +> : ^ + + selector?: (state: NoInfer) => TParam; +>selector : ((state: NoInfer) => TParam) | undefined +> : ^^ ^^ ^^^^^ ^^^^^^^^^^^^^ +>state : NoInfer +> : ^^^^^^^^^^ + + children?: (state: NoInfer) => React.ReactElement | null; +>children : ((state: NoInfer) => React.ReactElement | null) | undefined +> : ^^ ^^ ^^^^^ ^^^^^^^^^^^^^ +>state : NoInfer +> : ^^^^^^^^^^^^^^^ +>React : any +> : ^^^ + +}) => React.ReactElement; +>React : any +> : ^^^ + +declare const TestComponentWithoutChildren: (props: { +>TestComponentWithoutChildren : (props: { state: T; selector?: (state: NoInfer) => TParam; notChildren?: (state: NoInfer) => React.ReactElement | null; }) => React.ReactElement +> : ^ ^^ ^^ ^^ ^^^^^ +>props : { state: T; selector?: (state: NoInfer) => TParam; notChildren?: (state: NoInfer) => React.ReactElement | null; } +> : ^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^ ^^^ + + state: T; +>state : T +> : ^ + + selector?: (state: NoInfer) => TParam; +>selector : ((state: NoInfer) => TParam) | undefined +> : ^^ ^^ ^^^^^ ^^^^^^^^^^^^^ +>state : NoInfer +> : ^^^^^^^^^^ + + notChildren?: (state: NoInfer) => React.ReactElement | null; +>notChildren : ((state: NoInfer) => React.ReactElement | null) | undefined +> : ^^ ^^ ^^^^^ ^^^^^^^^^^^^^ +>state : NoInfer +> : ^^^^^^^^^^^^^^^ +>React : any +> : ^^^ + +}) => React.ReactElement; +>React : any +> : ^^^ + +const App = () => { +>App : () => JSX.Element +> : ^^^^^^^^^^^^^^^^^ +>() => { return ( <> state.foo}> {(selected) =>
{Math.max(selected, 0)}
}
state.foo} notChildren={(selected) =>
{Math.max(selected, 0)}
} /> );} : () => JSX.Element +> : ^^^^^^^^^^^^^^^^^ + + return ( +>( <> state.foo}> {(selected) =>
{Math.max(selected, 0)}
}
state.foo} notChildren={(selected) =>
{Math.max(selected, 0)}
} /> ) : JSX.Element +> : ^^^^^^^^^^^ + + <> +><> state.foo}> {(selected) =>
{Math.max(selected, 0)}
}
state.foo} notChildren={(selected) =>
{Math.max(selected, 0)}
} /> : JSX.Element +> : ^^^^^^^^^^^ + + state.foo}> +> state.foo}> {(selected) =>
{Math.max(selected, 0)}
}
: JSX.Element +> : ^^^^^^^^^^^ +>TestComponentWithChildren : (props: { state: T; selector?: (state: NoInfer) => TParam; children?: (state: NoInfer) => React.ReactElement | null; }) => React.ReactElement +> : ^ ^^ ^^ ^^ ^^^^^ +>state : { foo: number; } +> : ^^^^^^^^^^^^^^^^ +>{ foo: 123 } : { foo: number; } +> : ^^^^^^^^^^^^^^^^ +>foo : number +> : ^^^^^^ +>123 : 123 +> : ^^^ +>selector : (state: NoInfer<{ foo: number; }>) => number +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>(state) => state.foo : (state: NoInfer<{ foo: number; }>) => number +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>state : NoInfer<{ foo: number; }> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ +>state.foo : number +> : ^^^^^^ +>state : { foo: number; } +> : ^^^^^^^^^^^^^^^^ +>foo : number +> : ^^^^^^ + + {(selected) =>
{Math.max(selected, 0)}
} +>(selected) =>
{Math.max(selected, 0)}
: (selected: number) => JSX.Element +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^ +>selected : number +> : ^^^^^^ +>
{Math.max(selected, 0)}
: JSX.Element +> : ^^^^^^^^^^^ +>div : any +> : ^^^ +>Math.max(selected, 0) : number +> : ^^^^^^ +>Math.max : (...values: number[]) => number +> : ^^^^ ^^ ^^^^^ +>Math : Math +> : ^^^^ +>max : (...values: number[]) => number +> : ^^^^ ^^ ^^^^^ +>selected : number +> : ^^^^^^ +>0 : 0 +> : ^ +>div : any +> : ^^^ + +
+>TestComponentWithChildren : (props: { state: T; selector?: (state: NoInfer) => TParam; children?: (state: NoInfer) => React.ReactElement | null; }) => React.ReactElement +> : ^ ^^ ^^ ^^ ^^^^^ + + state.foo} notChildren={(selected) =>
{Math.max(selected, 0)}
} /> : JSX.Element +> : ^^^^^^^^^^^ +>TestComponentWithoutChildren : (props: { state: T; selector?: (state: NoInfer) => TParam; notChildren?: (state: NoInfer) => React.ReactElement | null; }) => React.ReactElement +> : ^ ^^ ^^ ^^ ^^^^^ + + state={{ foo: 123 }} +>state : { foo: number; } +> : ^^^^^^^^^^^^^^^^ +>{ foo: 123 } : { foo: number; } +> : ^^^^^^^^^^^^^^^^ +>foo : number +> : ^^^^^^ +>123 : 123 +> : ^^^ + + selector={(state) => state.foo} +>selector : (state: NoInfer<{ foo: number; }>) => number +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>(state) => state.foo : (state: NoInfer<{ foo: number; }>) => number +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>state : NoInfer<{ foo: number; }> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ +>state.foo : number +> : ^^^^^^ +>state : { foo: number; } +> : ^^^^^^^^^^^^^^^^ +>foo : number +> : ^^^^^^ + + notChildren={(selected) =>
{Math.max(selected, 0)}
} +>notChildren : (selected: number) => JSX.Element +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^ +>(selected) =>
{Math.max(selected, 0)}
: (selected: number) => JSX.Element +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^ +>selected : number +> : ^^^^^^ +>
{Math.max(selected, 0)}
: JSX.Element +> : ^^^^^^^^^^^ +>div : any +> : ^^^ +>Math.max(selected, 0) : number +> : ^^^^^^ +>Math.max : (...values: number[]) => number +> : ^^^^ ^^ ^^^^^ +>Math : Math +> : ^^^^ +>max : (...values: number[]) => number +> : ^^^^ ^^ ^^^^^ +>selected : number +> : ^^^^^^ +>0 : 0 +> : ^ +>div : any +> : ^^^ + + /> + + ); +}; + +// https://github.com/microsoft/typescript-go/issues/2797 + +interface State { + value: boolean +>value : boolean +> : ^^^^^^^ +} + +declare const Subscribe: (props: { +>Subscribe : (props: { selector?: (state: State) => TSelected; children: (state: TSelected) => void; }) => React.ReactElement +> : ^ ^^^^^^^^^^ ^^ ^^^^^ +>props : { selector?: (state: State) => TSelected; children: (state: TSelected) => void; } +> : ^^^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^ + + selector?: (state: State) => TSelected +>selector : ((state: State) => TSelected) | undefined +> : ^^ ^^ ^^^^^ ^^^^^^^^^^^^^ +>state : State +> : ^^^^^ + + children: (state: TSelected) => void +>children : (state: TSelected) => void +> : ^ ^^ ^^^^^ +>state : TSelected +> : ^^^^^^^^^ + +}) => React.ReactElement +>React : any +> : ^^^ + +const _result = ( +>_result : JSX.Element +> : ^^^^^^^^^^^ +>( { return [state.value] }} > {([value = false]) => { console.log(value) }} ) : JSX.Element +> : ^^^^^^^^^^^ + + { return [state.value] }} > {([value = false]) => { console.log(value) }} : JSX.Element +> : ^^^^^^^^^^^ +>Subscribe : (props: { selector?: (state: State) => TSelected; children: (state: TSelected) => void; }) => React.ReactElement +> : ^ ^^^^^^^^^^ ^^ ^^^^^ + + selector={(state) => { +>selector : (state: State) => boolean[] +> : ^ ^^^^^^^^^^^^^^^^^^^^^ +>(state) => { return [state.value] } : (state: State) => boolean[] +> : ^ ^^^^^^^^^^^^^^^^^^^^^ +>state : State +> : ^^^^^ + + return [state.value] +>[state.value] : boolean[] +> : ^^^^^^^^^ +>state.value : boolean +> : ^^^^^^^ +>state : State +> : ^^^^^ +>value : boolean +> : ^^^^^^^ + + }} + > + {([value = false]) => { +>([value = false]) => { console.log(value) } : ([value]: boolean[]) => void +> : ^ ^^^^^^^^^^^^^^^^^^^^ +>value : boolean +> : ^^^^^^^ +>false : false +> : ^^^^^ + + console.log(value) +>console.log(value) : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>value : boolean +> : ^^^^^^^ + + }} + +>Subscribe : (props: { selector?: (state: State) => TSelected; children: (state: TSelected) => void; }) => React.ReactElement +> : ^ ^^^^^^^^^^ ^^ ^^^^^ + +) + diff --git a/tests/baselines/reference/jsxFunctionTypeChildren.symbols b/tests/baselines/reference/jsxFunctionTypeChildren.symbols new file mode 100644 index 0000000000000..cd10cb0344480 --- /dev/null +++ b/tests/baselines/reference/jsxFunctionTypeChildren.symbols @@ -0,0 +1,70 @@ +//// [tests/cases/compiler/jsxFunctionTypeChildren.tsx] //// + +=== jsxFunctionTypeChildren.tsx === +// https://github.com/microsoft/typescript-go/issues/2703 + +/// + +import * as React from 'react'; +>React : Symbol(React, Decl(jsxFunctionTypeChildren.tsx, 4, 6)) + +type BaseProps = { locale: string }; +>BaseProps : Symbol(BaseProps, Decl(jsxFunctionTypeChildren.tsx, 4, 31)) +>locale : Symbol(locale, Decl(jsxFunctionTypeChildren.tsx, 6, 18)) + +type Props = { +>Props : Symbol(Props, Decl(jsxFunctionTypeChildren.tsx, 6, 36)) +>T : Symbol(T, Decl(jsxFunctionTypeChildren.tsx, 8, 11)) +>BaseProps : Symbol(BaseProps, Decl(jsxFunctionTypeChildren.tsx, 4, 31)) + + children: (props: T) => React.ReactNode; +>children : Symbol(children, Decl(jsxFunctionTypeChildren.tsx, 8, 35)) +>props : Symbol(props, Decl(jsxFunctionTypeChildren.tsx, 9, 15)) +>T : Symbol(T, Decl(jsxFunctionTypeChildren.tsx, 8, 11)) +>React : Symbol(React, Decl(jsxFunctionTypeChildren.tsx, 4, 6)) +>ReactNode : Symbol(React.ReactNode, Decl(react16.d.ts, 216, 49)) + +} & T; +>T : Symbol(T, Decl(jsxFunctionTypeChildren.tsx, 8, 11)) + +declare function Comp(props: Props): JSX.Element; +>Comp : Symbol(Comp, Decl(jsxFunctionTypeChildren.tsx, 10, 6)) +>T : Symbol(T, Decl(jsxFunctionTypeChildren.tsx, 12, 22)) +>BaseProps : Symbol(BaseProps, Decl(jsxFunctionTypeChildren.tsx, 4, 31)) +>props : Symbol(props, Decl(jsxFunctionTypeChildren.tsx, 12, 43)) +>Props : Symbol(Props, Decl(jsxFunctionTypeChildren.tsx, 6, 36)) +>T : Symbol(T, Decl(jsxFunctionTypeChildren.tsx, 12, 22)) +>JSX : Symbol(JSX, Decl(react16.d.ts, 2495, 12)) +>Element : Symbol(JSX.Element, Decl(react16.d.ts, 2496, 23)) + +const bp: BaseProps = { locale: 'en' }; +>bp : Symbol(bp, Decl(jsxFunctionTypeChildren.tsx, 14, 5)) +>BaseProps : Symbol(BaseProps, Decl(jsxFunctionTypeChildren.tsx, 4, 31)) +>locale : Symbol(locale, Decl(jsxFunctionTypeChildren.tsx, 14, 23)) + +// Error in ts-go: Type '(props: ...) => Element' is not assignable to +// type '((props: ...) => ReactNode) & {}'. +const el = {(props) =>
{props.locale}
}
; +>el : Symbol(el, Decl(jsxFunctionTypeChildren.tsx, 18, 5)) +>Comp : Symbol(Comp, Decl(jsxFunctionTypeChildren.tsx, 10, 6)) +>bp : Symbol(bp, Decl(jsxFunctionTypeChildren.tsx, 14, 5)) +>props : Symbol(props, Decl(jsxFunctionTypeChildren.tsx, 18, 27)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2548, 114)) +>props.locale : Symbol(locale, Decl(jsxFunctionTypeChildren.tsx, 6, 18)) +>props : Symbol(props, Decl(jsxFunctionTypeChildren.tsx, 18, 27)) +>locale : Symbol(locale, Decl(jsxFunctionTypeChildren.tsx, 6, 18)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2548, 114)) +>Comp : Symbol(Comp, Decl(jsxFunctionTypeChildren.tsx, 10, 6)) + +// But the equivalent non-JSX call works fine: +Comp({ ...bp, children: (props) =>
{props.locale}
}); +>Comp : Symbol(Comp, Decl(jsxFunctionTypeChildren.tsx, 10, 6)) +>bp : Symbol(bp, Decl(jsxFunctionTypeChildren.tsx, 14, 5)) +>children : Symbol(children, Decl(jsxFunctionTypeChildren.tsx, 21, 13)) +>props : Symbol(props, Decl(jsxFunctionTypeChildren.tsx, 21, 25)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2548, 114)) +>props.locale : Symbol(locale, Decl(jsxFunctionTypeChildren.tsx, 6, 18)) +>props : Symbol(props, Decl(jsxFunctionTypeChildren.tsx, 21, 25)) +>locale : Symbol(locale, Decl(jsxFunctionTypeChildren.tsx, 6, 18)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2548, 114)) + diff --git a/tests/baselines/reference/jsxFunctionTypeChildren.types b/tests/baselines/reference/jsxFunctionTypeChildren.types new file mode 100644 index 0000000000000..505b4bac9862e --- /dev/null +++ b/tests/baselines/reference/jsxFunctionTypeChildren.types @@ -0,0 +1,114 @@ +//// [tests/cases/compiler/jsxFunctionTypeChildren.tsx] //// + +=== Performance Stats === +Assignability cache: 2,500 +Type Count: 10,000 +Instantiation count: 100,000 +Symbol count: 100,000 + +=== jsxFunctionTypeChildren.tsx === +// https://github.com/microsoft/typescript-go/issues/2703 + +/// + +import * as React from 'react'; +>React : typeof React +> : ^^^^^^^^^^^^ + +type BaseProps = { locale: string }; +>BaseProps : BaseProps +> : ^^^^^^^^^ +>locale : string +> : ^^^^^^ + +type Props = { +>Props : Props +> : ^^^^^^^^ + + children: (props: T) => React.ReactNode; +>children : (props: T) => React.ReactNode +> : ^ ^^ ^^^^^ +>props : T +> : ^ +>React : any +> : ^^^ + +} & T; + +declare function Comp(props: Props): JSX.Element; +>Comp : (props: Props) => JSX.Element +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>props : Props +> : ^^^^^^^^ +>JSX : any +> : ^^^ + +const bp: BaseProps = { locale: 'en' }; +>bp : BaseProps +> : ^^^^^^^^^ +>{ locale: 'en' } : { locale: string; } +> : ^^^^^^^^^^^^^^^^^^^ +>locale : string +> : ^^^^^^ +>'en' : "en" +> : ^^^^ + +// Error in ts-go: Type '(props: ...) => Element' is not assignable to +// type '((props: ...) => ReactNode) & {}'. +const el = {(props) =>
{props.locale}
}
; +>el : JSX.Element +> : ^^^^^^^^^^^ +>{(props) =>
{props.locale}
}
: JSX.Element +> : ^^^^^^^^^^^ +>Comp : (props: Props) => JSX.Element +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>bp : BaseProps +> : ^^^^^^^^^ +>(props) =>
{props.locale}
: (props: BaseProps) => JSX.Element +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>props : BaseProps +> : ^^^^^^^^^ +>
{props.locale}
: JSX.Element +> : ^^^^^^^^^^^ +>div : any +> : ^^^ +>props.locale : string +> : ^^^^^^ +>props : BaseProps +> : ^^^^^^^^^ +>locale : string +> : ^^^^^^ +>div : any +> : ^^^ +>Comp : (props: Props) => JSX.Element +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ + +// But the equivalent non-JSX call works fine: +Comp({ ...bp, children: (props) =>
{props.locale}
}); +>Comp({ ...bp, children: (props) =>
{props.locale}
}) : JSX.Element +> : ^^^^^^^^^^^ +>Comp : (props: Props) => JSX.Element +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>{ ...bp, children: (props) =>
{props.locale}
} : { children: (props: BaseProps) => JSX.Element; locale: string; } +> : ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ +>bp : BaseProps +> : ^^^^^^^^^ +>children : (props: BaseProps) => JSX.Element +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>(props) =>
{props.locale}
: (props: BaseProps) => JSX.Element +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>props : BaseProps +> : ^^^^^^^^^ +>
{props.locale}
: JSX.Element +> : ^^^^^^^^^^^ +>div : any +> : ^^^ +>props.locale : string +> : ^^^^^^ +>props : BaseProps +> : ^^^^^^^^^ +>locale : string +> : ^^^^^^ +>div : any +> : ^^^ + diff --git a/tests/baselines/reference/subtypeReductionWithAnyFunctionType.errors.txt b/tests/baselines/reference/subtypeReductionWithAnyFunctionType.errors.txt new file mode 100644 index 0000000000000..7c570e0e9694f --- /dev/null +++ b/tests/baselines/reference/subtypeReductionWithAnyFunctionType.errors.txt @@ -0,0 +1,31 @@ +subtypeReductionWithAnyFunctionType.ts(10,16): error TS7006: Parameter 'x' implicitly has an 'any' type. + + +==== subtypeReductionWithAnyFunctionType.ts (1 errors) ==== + // https://github.com/microsoft/typescript-go/issues/849 + + declare function useMemo(func: () => T): T; + + function getPredicate(alwaysTrue: boolean) { + const predicate: (input: string) => boolean = useMemo(() => { + if (alwaysTrue) { + return () => true; + } + return x => x.length > 0; + ~ +!!! error TS7006: Parameter 'x' implicitly has an 'any' type. + }); + return predicate; + } + + // https://github.com/microsoft/typescript-go/issues/1016 + + declare function compact(array: T[]): T[]; + declare function makeFooer(): Fooer; + interface Fooer { + foo: (v: string) => string; + } + function f() { + const _ = compact([makeFooer(), { foo: (v) => v }]); + } + \ No newline at end of file diff --git a/tests/baselines/reference/subtypeReductionWithAnyFunctionType.symbols b/tests/baselines/reference/subtypeReductionWithAnyFunctionType.symbols new file mode 100644 index 0000000000000..c348637d5ada5 --- /dev/null +++ b/tests/baselines/reference/subtypeReductionWithAnyFunctionType.symbols @@ -0,0 +1,67 @@ +//// [tests/cases/compiler/subtypeReductionWithAnyFunctionType.ts] //// + +=== subtypeReductionWithAnyFunctionType.ts === +// https://github.com/microsoft/typescript-go/issues/849 + +declare function useMemo(func: () => T): T; +>useMemo : Symbol(useMemo, Decl(subtypeReductionWithAnyFunctionType.ts, 0, 0)) +>T : Symbol(T, Decl(subtypeReductionWithAnyFunctionType.ts, 2, 25)) +>func : Symbol(func, Decl(subtypeReductionWithAnyFunctionType.ts, 2, 28)) +>T : Symbol(T, Decl(subtypeReductionWithAnyFunctionType.ts, 2, 25)) +>T : Symbol(T, Decl(subtypeReductionWithAnyFunctionType.ts, 2, 25)) + +function getPredicate(alwaysTrue: boolean) { +>getPredicate : Symbol(getPredicate, Decl(subtypeReductionWithAnyFunctionType.ts, 2, 46)) +>alwaysTrue : Symbol(alwaysTrue, Decl(subtypeReductionWithAnyFunctionType.ts, 4, 22)) + + const predicate: (input: string) => boolean = useMemo(() => { +>predicate : Symbol(predicate, Decl(subtypeReductionWithAnyFunctionType.ts, 5, 9)) +>input : Symbol(input, Decl(subtypeReductionWithAnyFunctionType.ts, 5, 22)) +>useMemo : Symbol(useMemo, Decl(subtypeReductionWithAnyFunctionType.ts, 0, 0)) + + if (alwaysTrue) { +>alwaysTrue : Symbol(alwaysTrue, Decl(subtypeReductionWithAnyFunctionType.ts, 4, 22)) + + return () => true; + } + return x => x.length > 0; +>x : Symbol(x, Decl(subtypeReductionWithAnyFunctionType.ts, 9, 14)) +>x : Symbol(x, Decl(subtypeReductionWithAnyFunctionType.ts, 9, 14)) + + }); + return predicate; +>predicate : Symbol(predicate, Decl(subtypeReductionWithAnyFunctionType.ts, 5, 9)) +} + +// https://github.com/microsoft/typescript-go/issues/1016 + +declare function compact(array: T[]): T[]; +>compact : Symbol(compact, Decl(subtypeReductionWithAnyFunctionType.ts, 12, 1)) +>T : Symbol(T, Decl(subtypeReductionWithAnyFunctionType.ts, 16, 25)) +>array : Symbol(array, Decl(subtypeReductionWithAnyFunctionType.ts, 16, 28)) +>T : Symbol(T, Decl(subtypeReductionWithAnyFunctionType.ts, 16, 25)) +>T : Symbol(T, Decl(subtypeReductionWithAnyFunctionType.ts, 16, 25)) + +declare function makeFooer(): Fooer; +>makeFooer : Symbol(makeFooer, Decl(subtypeReductionWithAnyFunctionType.ts, 16, 45)) +>Fooer : Symbol(Fooer, Decl(subtypeReductionWithAnyFunctionType.ts, 17, 36)) + +interface Fooer { +>Fooer : Symbol(Fooer, Decl(subtypeReductionWithAnyFunctionType.ts, 17, 36)) + + foo: (v: string) => string; +>foo : Symbol(Fooer.foo, Decl(subtypeReductionWithAnyFunctionType.ts, 18, 17)) +>v : Symbol(v, Decl(subtypeReductionWithAnyFunctionType.ts, 19, 10)) +} +function f() { +>f : Symbol(f, Decl(subtypeReductionWithAnyFunctionType.ts, 20, 1)) + + const _ = compact([makeFooer(), { foo: (v) => v }]); +>_ : Symbol(_, Decl(subtypeReductionWithAnyFunctionType.ts, 22, 9)) +>compact : Symbol(compact, Decl(subtypeReductionWithAnyFunctionType.ts, 12, 1)) +>makeFooer : Symbol(makeFooer, Decl(subtypeReductionWithAnyFunctionType.ts, 16, 45)) +>foo : Symbol(foo, Decl(subtypeReductionWithAnyFunctionType.ts, 22, 37)) +>v : Symbol(v, Decl(subtypeReductionWithAnyFunctionType.ts, 22, 44)) +>v : Symbol(v, Decl(subtypeReductionWithAnyFunctionType.ts, 22, 44)) +} + diff --git a/tests/baselines/reference/subtypeReductionWithAnyFunctionType.types b/tests/baselines/reference/subtypeReductionWithAnyFunctionType.types new file mode 100644 index 0000000000000..98f756e407cc4 --- /dev/null +++ b/tests/baselines/reference/subtypeReductionWithAnyFunctionType.types @@ -0,0 +1,109 @@ +//// [tests/cases/compiler/subtypeReductionWithAnyFunctionType.ts] //// + +=== subtypeReductionWithAnyFunctionType.ts === +// https://github.com/microsoft/typescript-go/issues/849 + +declare function useMemo(func: () => T): T; +>useMemo : (func: () => T) => T +> : ^ ^^ ^^ ^^^^^ +>func : () => T +> : ^^^^^^ + +function getPredicate(alwaysTrue: boolean) { +>getPredicate : (alwaysTrue: boolean) => (input: string) => boolean +> : ^ ^^ ^^^^^^ ^^ ^^^^^ +>alwaysTrue : boolean +> : ^^^^^^^ + + const predicate: (input: string) => boolean = useMemo(() => { +>predicate : (input: string) => boolean +> : ^ ^^ ^^^^^ +>input : string +> : ^^^^^^ +>useMemo(() => { if (alwaysTrue) { return () => true; } return x => x.length > 0; }) : (x: any) => boolean +> : ^ ^^^^^^^^^^^^^^^^^ +>useMemo : (func: () => T) => T +> : ^ ^^ ^^ ^^^^^ +>() => { if (alwaysTrue) { return () => true; } return x => x.length > 0; } : () => (x: any) => boolean +> : ^^^^^^^ ^^^^^^^^^^^^^^^^^ + + if (alwaysTrue) { +>alwaysTrue : boolean +> : ^^^^^^^ + + return () => true; +>() => true : () => true +> : ^^^^^^^^^^ +>true : true +> : ^^^^ + } + return x => x.length > 0; +>x => x.length > 0 : (x: any) => boolean +> : ^ ^^^^^^^^^^^^^^^^^ +>x : any +> : ^^^ +>x.length > 0 : boolean +> : ^^^^^^^ +>x.length : any +> : ^^^ +>x : any +> : ^^^ +>length : any +> : ^^^ +>0 : 0 +> : ^ + + }); + return predicate; +>predicate : (input: string) => boolean +> : ^ ^^ ^^^^^ +} + +// https://github.com/microsoft/typescript-go/issues/1016 + +declare function compact(array: T[]): T[]; +>compact : (array: T[]) => T[] +> : ^ ^^ ^^ ^^^^^ +>array : T[] +> : ^^^ + +declare function makeFooer(): Fooer; +>makeFooer : () => Fooer +> : ^^^^^^ + +interface Fooer { + foo: (v: string) => string; +>foo : (v: string) => string +> : ^ ^^ ^^^^^ +>v : string +> : ^^^^^^ +} +function f() { +>f : () => void +> : ^^^^^^^^^^ + + const _ = compact([makeFooer(), { foo: (v) => v }]); +>_ : Fooer[] +> : ^^^^^^^ +>compact([makeFooer(), { foo: (v) => v }]) : Fooer[] +> : ^^^^^^^ +>compact : (array: T[]) => T[] +> : ^ ^^ ^^ ^^^^^ +>[makeFooer(), { foo: (v) => v }] : Fooer[] +> : ^^^^^^^ +>makeFooer() : Fooer +> : ^^^^^ +>makeFooer : () => Fooer +> : ^^^^^^ +>{ foo: (v) => v } : { foo: (v: string) => string; } +> : ^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^ +>foo : (v: string) => string +> : ^ ^^^^^^^^^^^^^^^^^^^ +>(v) => v : (v: string) => string +> : ^ ^^^^^^^^^^^^^^^^^^^ +>v : string +> : ^^^^^^ +>v : string +> : ^^^^^^ +} + diff --git a/tests/cases/compiler/contextuallyTypedJsxChildren2.tsx b/tests/cases/compiler/contextuallyTypedJsxChildren2.tsx new file mode 100644 index 0000000000000..3a63b5fd57a3e --- /dev/null +++ b/tests/cases/compiler/contextuallyTypedJsxChildren2.tsx @@ -0,0 +1,62 @@ +// @target: es2015 +// @strict: true +// @jsx: react +// @esModuleInterop: true +// @noEmit: true + +/// + +// https://github.com/microsoft/typescript-go/issues/2802 + +import * as React from 'react'; + +declare const TestComponentWithChildren: (props: { + state: T; + selector?: (state: NoInfer) => TParam; + children?: (state: NoInfer) => React.ReactElement | null; +}) => React.ReactElement; + +declare const TestComponentWithoutChildren: (props: { + state: T; + selector?: (state: NoInfer) => TParam; + notChildren?: (state: NoInfer) => React.ReactElement | null; +}) => React.ReactElement; + +const App = () => { + return ( + <> + state.foo}> + {(selected) =>
{Math.max(selected, 0)}
} +
+ + state.foo} + notChildren={(selected) =>
{Math.max(selected, 0)}
} + /> + + ); +}; + +// https://github.com/microsoft/typescript-go/issues/2797 + +interface State { + value: boolean +} + +declare const Subscribe: (props: { + selector?: (state: State) => TSelected + children: (state: TSelected) => void +}) => React.ReactElement + +const _result = ( + { + return [state.value] + }} + > + {([value = false]) => { + console.log(value) + }} + +) diff --git a/tests/cases/compiler/jsxFunctionTypeChildren.tsx b/tests/cases/compiler/jsxFunctionTypeChildren.tsx new file mode 100644 index 0000000000000..9dfceb6b89ba2 --- /dev/null +++ b/tests/cases/compiler/jsxFunctionTypeChildren.tsx @@ -0,0 +1,27 @@ +// @strict: true +// @target: esnext +// @noEmit: true +// @jsx: preserve + +// https://github.com/microsoft/typescript-go/issues/2703 + +/// + +import * as React from 'react'; + +type BaseProps = { locale: string }; + +type Props = { + children: (props: T) => React.ReactNode; +} & T; + +declare function Comp(props: Props): JSX.Element; + +const bp: BaseProps = { locale: 'en' }; + +// Error in ts-go: Type '(props: ...) => Element' is not assignable to +// type '((props: ...) => ReactNode) & {}'. +const el = {(props) =>
{props.locale}
}
; + +// But the equivalent non-JSX call works fine: +Comp({ ...bp, children: (props) =>
{props.locale}
}); diff --git a/tests/cases/compiler/subtypeReductionWithAnyFunctionType.ts b/tests/cases/compiler/subtypeReductionWithAnyFunctionType.ts new file mode 100644 index 0000000000000..e45c648dc8484 --- /dev/null +++ b/tests/cases/compiler/subtypeReductionWithAnyFunctionType.ts @@ -0,0 +1,28 @@ +// @strict: true +// @target: esnext +// @noEmit: true + +// https://github.com/microsoft/typescript-go/issues/849 + +declare function useMemo(func: () => T): T; + +function getPredicate(alwaysTrue: boolean) { + const predicate: (input: string) => boolean = useMemo(() => { + if (alwaysTrue) { + return () => true; + } + return x => x.length > 0; + }); + return predicate; +} + +// https://github.com/microsoft/typescript-go/issues/1016 + +declare function compact(array: T[]): T[]; +declare function makeFooer(): Fooer; +interface Fooer { + foo: (v: string) => string; +} +function f() { + const _ = compact([makeFooer(), { foo: (v) => v }]); +}