diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d627a55ce8b5b..38d7842183a4f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -55,7 +55,9 @@ namespace ts { const enum WideningKind { Normal, - GeneratorYield + FunctionReturn, + GeneratorNext, + GeneratorYield, } const enum TypeFacts { @@ -18080,7 +18082,7 @@ namespace ts { } function reportErrorsFromWidening(declaration: Declaration, type: Type, wideningKind?: WideningKind) { - if (produceDiagnostics && noImplicitAny && getObjectFlags(type) & ObjectFlags.ContainsWideningType) { + if (produceDiagnostics && noImplicitAny && getObjectFlags(type) & ObjectFlags.ContainsWideningType && (!wideningKind || !getContextualSignatureForFunctionLikeDeclaration(declaration as FunctionLikeDeclaration))) { // Report implicit any error within type if possible, otherwise report error on declaration if (!reportWideningErrorsInType(type)) { reportImplicitAny(declaration, type, wideningKind); @@ -27030,15 +27032,13 @@ namespace ts { } if (returnType || yieldType || nextType) { - const contextualSignature = getContextualSignatureForFunctionLikeDeclaration(func); - if (!contextualSignature) { - if (yieldType) reportErrorsFromWidening(func, yieldType, WideningKind.GeneratorYield); - if (returnType) reportErrorsFromWidening(func, returnType); - if (nextType) reportErrorsFromWidening(func, nextType); - } + if (yieldType) reportErrorsFromWidening(func, yieldType, WideningKind.GeneratorYield); + if (returnType) reportErrorsFromWidening(func, returnType, WideningKind.FunctionReturn); + if (nextType) reportErrorsFromWidening(func, nextType, WideningKind.GeneratorNext); if (returnType && isUnitType(returnType) || yieldType && isUnitType(yieldType) || nextType && isUnitType(nextType)) { + const contextualSignature = getContextualSignatureForFunctionLikeDeclaration(func); const contextualType = !contextualSignature ? undefined : contextualSignature === getSignatureFromDeclaration(func) ? isGenerator ? undefined : returnType : instantiateContextualType(getReturnTypeOfSignature(contextualSignature), func); diff --git a/tests/baselines/reference/reverseMappedTypeContextualTypeNotCircular.errors.txt b/tests/baselines/reference/reverseMappedTypeContextualTypeNotCircular.errors.txt new file mode 100644 index 0000000000000..d5462d0d0b7dc --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeContextualTypeNotCircular.errors.txt @@ -0,0 +1,18 @@ +tests/cases/compiler/reverseMappedTypeContextualTypeNotCircular.ts(10,3): error TS2322: Type '(state: any, props: any) => {}' is not assignable to type 'Selector'. + + +==== tests/cases/compiler/reverseMappedTypeContextualTypeNotCircular.ts (1 errors) ==== + type Selector = (state: S) => R; + + declare function createStructuredSelector( + selectors: {[K in keyof T]: Selector}, + ): Selector; + + const editable = () => ({}); + + const mapStateToProps = createStructuredSelector({ + editable: (state: any, props: any) => editable(), // expect "Type '(state: any, props: any) => {}' is not assignable to type 'Selector'", _not_ a circularity error + ~~~~~~~~ +!!! error TS2322: Type '(state: any, props: any) => {}' is not assignable to type 'Selector'. +!!! related TS6500 tests/cases/compiler/reverseMappedTypeContextualTypeNotCircular.ts:10:3: The expected type comes from property 'editable' which is declared here on type '{ editable: Selector; }' + }); \ No newline at end of file diff --git a/tests/baselines/reference/reverseMappedTypeContextualTypeNotCircular.js b/tests/baselines/reference/reverseMappedTypeContextualTypeNotCircular.js new file mode 100644 index 0000000000000..66302e8e642c5 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeContextualTypeNotCircular.js @@ -0,0 +1,18 @@ +//// [reverseMappedTypeContextualTypeNotCircular.ts] +type Selector = (state: S) => R; + +declare function createStructuredSelector( + selectors: {[K in keyof T]: Selector}, +): Selector; + +const editable = () => ({}); + +const mapStateToProps = createStructuredSelector({ + editable: (state: any, props: any) => editable(), // expect "Type '(state: any, props: any) => {}' is not assignable to type 'Selector'", _not_ a circularity error +}); + +//// [reverseMappedTypeContextualTypeNotCircular.js] +var editable = function () { return ({}); }; +var mapStateToProps = createStructuredSelector({ + editable: function (state, props) { return editable(); } +}); diff --git a/tests/baselines/reference/reverseMappedTypeContextualTypeNotCircular.symbols b/tests/baselines/reference/reverseMappedTypeContextualTypeNotCircular.symbols new file mode 100644 index 0000000000000..94dcef3f0a310 --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeContextualTypeNotCircular.symbols @@ -0,0 +1,42 @@ +=== tests/cases/compiler/reverseMappedTypeContextualTypeNotCircular.ts === +type Selector = (state: S) => R; +>Selector : Symbol(Selector, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 0, 0)) +>S : Symbol(S, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 0, 14)) +>R : Symbol(R, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 0, 16)) +>state : Symbol(state, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 0, 23)) +>S : Symbol(S, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 0, 14)) +>R : Symbol(R, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 0, 16)) + +declare function createStructuredSelector( +>createStructuredSelector : Symbol(createStructuredSelector, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 0, 38)) +>S : Symbol(S, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 2, 42)) +>T : Symbol(T, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 2, 44)) + + selectors: {[K in keyof T]: Selector}, +>selectors : Symbol(selectors, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 2, 48)) +>K : Symbol(K, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 3, 15)) +>T : Symbol(T, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 2, 44)) +>Selector : Symbol(Selector, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 0, 0)) +>S : Symbol(S, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 2, 42)) +>T : Symbol(T, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 2, 44)) +>K : Symbol(K, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 3, 15)) + +): Selector; +>Selector : Symbol(Selector, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 0, 0)) +>S : Symbol(S, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 2, 42)) +>T : Symbol(T, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 2, 44)) + +const editable = () => ({}); +>editable : Symbol(editable, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 6, 5)) + +const mapStateToProps = createStructuredSelector({ +>mapStateToProps : Symbol(mapStateToProps, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 8, 5)) +>createStructuredSelector : Symbol(createStructuredSelector, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 0, 38)) + + editable: (state: any, props: any) => editable(), // expect "Type '(state: any, props: any) => {}' is not assignable to type 'Selector'", _not_ a circularity error +>editable : Symbol(editable, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 8, 50)) +>state : Symbol(state, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 9, 13)) +>props : Symbol(props, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 9, 24)) +>editable : Symbol(editable, Decl(reverseMappedTypeContextualTypeNotCircular.ts, 6, 5)) + +}); diff --git a/tests/baselines/reference/reverseMappedTypeContextualTypeNotCircular.types b/tests/baselines/reference/reverseMappedTypeContextualTypeNotCircular.types new file mode 100644 index 0000000000000..8f5d92f3d7d6b --- /dev/null +++ b/tests/baselines/reference/reverseMappedTypeContextualTypeNotCircular.types @@ -0,0 +1,34 @@ +=== tests/cases/compiler/reverseMappedTypeContextualTypeNotCircular.ts === +type Selector = (state: S) => R; +>Selector : Selector +>state : S + +declare function createStructuredSelector( +>createStructuredSelector : (selectors: { [K in keyof T]: Selector; }) => Selector + + selectors: {[K in keyof T]: Selector}, +>selectors : { [K in keyof T]: Selector; } + +): Selector; + +const editable = () => ({}); +>editable : () => {} +>() => ({}) : () => {} +>({}) : {} +>{} : {} + +const mapStateToProps = createStructuredSelector({ +>mapStateToProps : Selector +>createStructuredSelector({ editable: (state: any, props: any) => editable(), // expect "Type '(state: any, props: any) => {}' is not assignable to type 'Selector'", _not_ a circularity error}) : Selector +>createStructuredSelector : (selectors: { [K in keyof T]: Selector; }) => Selector +>{ editable: (state: any, props: any) => editable(), // expect "Type '(state: any, props: any) => {}' is not assignable to type 'Selector'", _not_ a circularity error} : { editable: (state: any, props: any) => {}; } + + editable: (state: any, props: any) => editable(), // expect "Type '(state: any, props: any) => {}' is not assignable to type 'Selector'", _not_ a circularity error +>editable : (state: any, props: any) => {} +>(state: any, props: any) => editable() : (state: any, props: any) => {} +>state : any +>props : any +>editable() : {} +>editable : () => {} + +}); diff --git a/tests/cases/compiler/reverseMappedTypeContextualTypeNotCircular.ts b/tests/cases/compiler/reverseMappedTypeContextualTypeNotCircular.ts new file mode 100644 index 0000000000000..e80b71610ac4b --- /dev/null +++ b/tests/cases/compiler/reverseMappedTypeContextualTypeNotCircular.ts @@ -0,0 +1,11 @@ +type Selector = (state: S) => R; + +declare function createStructuredSelector( + selectors: {[K in keyof T]: Selector}, +): Selector; + +const editable = () => ({}); + +const mapStateToProps = createStructuredSelector({ + editable: (state: any, props: any) => editable(), // expect "Type '(state: any, props: any) => {}' is not assignable to type 'Selector'", _not_ a circularity error +}); \ No newline at end of file