Delay pulling on signature contextual type until absolutely needed (#37851)

This commit is contained in:
Wesley Wigham 2020-04-21 13:29:45 -07:00 committed by GitHub
parent 136f728bb0
commit a72e49e875
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 131 additions and 8 deletions

View File

@ -55,7 +55,9 @@ namespace ts {
const enum WideningKind {
Normal,
GeneratorYield
FunctionReturn,
GeneratorNext,
GeneratorYield,
}
const enum TypeFacts {
@ -18092,7 +18094,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);
@ -27047,15 +27049,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);

View File

@ -0,0 +1,18 @@
tests/cases/compiler/reverseMappedTypeContextualTypeNotCircular.ts(10,3): error TS2322: Type '(state: any, props: any) => {}' is not assignable to type 'Selector<unknown, {}>'.
==== tests/cases/compiler/reverseMappedTypeContextualTypeNotCircular.ts (1 errors) ====
type Selector<S, R> = (state: S) => R;
declare function createStructuredSelector<S, T>(
selectors: {[K in keyof T]: Selector<S, T[K]>},
): Selector<S, T>;
const editable = () => ({});
const mapStateToProps = createStructuredSelector({
editable: (state: any, props: any) => editable(), // expect "Type '(state: any, props: any) => {}' is not assignable to type 'Selector<unknown, {}>'", _not_ a circularity error
~~~~~~~~
!!! error TS2322: Type '(state: any, props: any) => {}' is not assignable to type 'Selector<unknown, {}>'.
!!! related TS6500 tests/cases/compiler/reverseMappedTypeContextualTypeNotCircular.ts:10:3: The expected type comes from property 'editable' which is declared here on type '{ editable: Selector<unknown, {}>; }'
});

View File

@ -0,0 +1,18 @@
//// [reverseMappedTypeContextualTypeNotCircular.ts]
type Selector<S, R> = (state: S) => R;
declare function createStructuredSelector<S, T>(
selectors: {[K in keyof T]: Selector<S, T[K]>},
): Selector<S, T>;
const editable = () => ({});
const mapStateToProps = createStructuredSelector({
editable: (state: any, props: any) => editable(), // expect "Type '(state: any, props: any) => {}' is not assignable to type 'Selector<unknown, {}>'", _not_ a circularity error
});
//// [reverseMappedTypeContextualTypeNotCircular.js]
var editable = function () { return ({}); };
var mapStateToProps = createStructuredSelector({
editable: function (state, props) { return editable(); }
});

View File

@ -0,0 +1,42 @@
=== tests/cases/compiler/reverseMappedTypeContextualTypeNotCircular.ts ===
type Selector<S, R> = (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<S, T>(
>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<S, T[K]>},
>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<S, T>;
>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<unknown, {}>'", _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))
});

View File

@ -0,0 +1,34 @@
=== tests/cases/compiler/reverseMappedTypeContextualTypeNotCircular.ts ===
type Selector<S, R> = (state: S) => R;
>Selector : Selector<S, R>
>state : S
declare function createStructuredSelector<S, T>(
>createStructuredSelector : <S, T>(selectors: { [K in keyof T]: Selector<S, T[K]>; }) => Selector<S, T>
selectors: {[K in keyof T]: Selector<S, T[K]>},
>selectors : { [K in keyof T]: Selector<S, T[K]>; }
): Selector<S, T>;
const editable = () => ({});
>editable : () => {}
>() => ({}) : () => {}
>({}) : {}
>{} : {}
const mapStateToProps = createStructuredSelector({
>mapStateToProps : Selector<unknown, { editable: {}; }>
>createStructuredSelector({ editable: (state: any, props: any) => editable(), // expect "Type '(state: any, props: any) => {}' is not assignable to type 'Selector<unknown, {}>'", _not_ a circularity error}) : Selector<unknown, { editable: {}; }>
>createStructuredSelector : <S, T>(selectors: { [K in keyof T]: Selector<S, T[K]>; }) => Selector<S, T>
>{ editable: (state: any, props: any) => editable(), // expect "Type '(state: any, props: any) => {}' is not assignable to type 'Selector<unknown, {}>'", _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<unknown, {}>'", _not_ a circularity error
>editable : (state: any, props: any) => {}
>(state: any, props: any) => editable() : (state: any, props: any) => {}
>state : any
>props : any
>editable() : {}
>editable : () => {}
});

View File

@ -0,0 +1,11 @@
type Selector<S, R> = (state: S) => R;
declare function createStructuredSelector<S, T>(
selectors: {[K in keyof T]: Selector<S, T[K]>},
): Selector<S, T>;
const editable = () => ({});
const mapStateToProps = createStructuredSelector({
editable: (state: any, props: any) => editable(), // expect "Type '(state: any, props: any) => {}' is not assignable to type 'Selector<unknown, {}>'", _not_ a circularity error
});