Fix type import node circularity errors in eager diagnostic mode, deprecations (#52861)

This commit is contained in:
Jake Bailey 2023-02-21 15:42:15 -08:00 committed by GitHub
parent 8adc460c3c
commit 3471bd7d86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 199 additions and 14 deletions

View File

@ -14915,7 +14915,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const [childTypeParameter = declaration.parent, grandParent] = walkUpParenthesizedTypesAndGetParentAndChild(declaration.parent.parent);
if (grandParent.kind === SyntaxKind.TypeReference && !omitTypeReferences) {
const typeReference = grandParent as TypeReferenceNode;
const typeParameters = getTypeParametersForTypeReference(typeReference);
const typeParameters = getTypeParametersForTypeReferenceOrImport(typeReference);
if (typeParameters) {
const index = typeReference.typeArguments!.indexOf(childTypeParameter as TypeNode);
if (index < typeParameters.length) {
@ -17944,13 +17944,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return getInstantiationExpressionType(getTypeOfSymbol(symbol), node); // intentionally doesn't use resolved symbol so type is cached as expected on the alias
}
else {
const type = tryGetDeclaredTypeOfSymbol(resolvedSymbol); // call this first to ensure typeParameters is populated (if applicable)
const typeParameters = type && getTypeParametersForTypeAndSymbol(type, resolvedSymbol);
if (node.typeArguments && typeParameters) {
addLazyDiagnostic(() => {
checkTypeArgumentConstraints(node, typeParameters);
});
}
return getTypeReferenceType(node, resolvedSymbol); // getTypeReferenceType doesn't handle aliases - it must get the resolved symbol
}
}
@ -38326,8 +38319,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return undefined;
}
function getTypeParametersForTypeReference(node: TypeReferenceNode | ExpressionWithTypeArguments) {
const type = getTypeFromTypeReference(node);
function getTypeParametersForTypeReferenceOrImport(node: TypeReferenceNode | ExpressionWithTypeArguments | ImportTypeNode) {
const type = getTypeFromTypeNode(node);
if (!isErrorType(type)) {
const symbol = getNodeLinks(node).resolvedSymbol;
if (symbol) {
@ -38347,11 +38340,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
forEach(node.typeArguments, checkSourceElement);
const type = getTypeFromTypeReference(node);
checkTypeReferenceOrImport(node);
}
function checkTypeReferenceOrImport(node: TypeReferenceNode | ExpressionWithTypeArguments | ImportTypeNode) {
const type = getTypeFromTypeNode(node);
if (!isErrorType(type)) {
if (node.typeArguments) {
addLazyDiagnostic(() => {
const typeParameters = getTypeParametersForTypeReference(node);
const typeParameters = getTypeParametersForTypeReferenceOrImport(node);
if (typeParameters) {
checkTypeArgumentConstraints(node, typeParameters);
}
@ -38373,7 +38370,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function getTypeArgumentConstraint(node: TypeNode): Type | undefined {
const typeReferenceNode = tryCast(node.parent, isTypeReferenceType);
if (!typeReferenceNode) return undefined;
const typeParameters = getTypeParametersForTypeReference(typeReferenceNode);
const typeParameters = getTypeParametersForTypeReferenceOrImport(typeReferenceNode);
if (!typeParameters) return undefined;
const constraint = getConstraintOfTypeParameter(typeParameters[typeReferenceNode.typeArguments!.indexOf(node)]);
return constraint && instantiateType(constraint, createTypeMapper(typeParameters, getEffectiveTypeArguments(typeReferenceNode, typeParameters)));
@ -38576,7 +38573,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
getTypeFromTypeNode(node);
checkTypeReferenceOrImport(node);
}
function checkNamedTupleMember(node: NamedTupleMember) {

View File

@ -0,0 +1,28 @@
//// [tests/cases/compiler/spuriousCircularityOnTypeImport.ts] ////
//// [types.ts]
export type SelectorMap<T extends Record<string, (...params: unknown[]) => unknown>> = {
[key in keyof T]: T[key];
};
//// [index.ts]
export type SelectorMap<T extends Record<string, (...params: unknown[]) => unknown>> = {
[key in keyof T]: T[key];
};
export declare const value2: {
sliceSelectors: <FuncMap extends import('./types').SelectorMap<FuncMap>>(selectorsBySlice: FuncMap) => { [P in keyof FuncMap]: Parameters<FuncMap[P]> };
};
export declare const value3: {
sliceSelectors: <FuncMap extends SelectorMap<FuncMap>>(selectorsBySlice: FuncMap) => { [P in keyof FuncMap]: Parameters<FuncMap[P]> };
};
//// [types.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//// [index.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@ -0,0 +1,67 @@
=== tests/cases/compiler/types.ts ===
export type SelectorMap<T extends Record<string, (...params: unknown[]) => unknown>> = {
>SelectorMap : Symbol(SelectorMap, Decl(types.ts, 0, 0))
>T : Symbol(T, Decl(types.ts, 0, 24))
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
>params : Symbol(params, Decl(types.ts, 0, 50))
[key in keyof T]: T[key];
>key : Symbol(key, Decl(types.ts, 1, 5))
>T : Symbol(T, Decl(types.ts, 0, 24))
>T : Symbol(T, Decl(types.ts, 0, 24))
>key : Symbol(key, Decl(types.ts, 1, 5))
};
=== tests/cases/compiler/index.ts ===
export type SelectorMap<T extends Record<string, (...params: unknown[]) => unknown>> = {
>SelectorMap : Symbol(SelectorMap, Decl(index.ts, 0, 0))
>T : Symbol(T, Decl(index.ts, 0, 24))
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
>params : Symbol(params, Decl(index.ts, 0, 50))
[key in keyof T]: T[key];
>key : Symbol(key, Decl(index.ts, 1, 5))
>T : Symbol(T, Decl(index.ts, 0, 24))
>T : Symbol(T, Decl(index.ts, 0, 24))
>key : Symbol(key, Decl(index.ts, 1, 5))
};
export declare const value2: {
>value2 : Symbol(value2, Decl(index.ts, 4, 20))
sliceSelectors: <FuncMap extends import('./types').SelectorMap<FuncMap>>(selectorsBySlice: FuncMap) => { [P in keyof FuncMap]: Parameters<FuncMap[P]> };
>sliceSelectors : Symbol(sliceSelectors, Decl(index.ts, 4, 30))
>FuncMap : Symbol(FuncMap, Decl(index.ts, 5, 21))
>SelectorMap : Symbol(SelectorMap, Decl(types.ts, 0, 0))
>FuncMap : Symbol(FuncMap, Decl(index.ts, 5, 21))
>selectorsBySlice : Symbol(selectorsBySlice, Decl(index.ts, 5, 77))
>FuncMap : Symbol(FuncMap, Decl(index.ts, 5, 21))
>P : Symbol(P, Decl(index.ts, 5, 110))
>FuncMap : Symbol(FuncMap, Decl(index.ts, 5, 21))
>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --))
>FuncMap : Symbol(FuncMap, Decl(index.ts, 5, 21))
>P : Symbol(P, Decl(index.ts, 5, 110))
};
export declare const value3: {
>value3 : Symbol(value3, Decl(index.ts, 8, 20))
sliceSelectors: <FuncMap extends SelectorMap<FuncMap>>(selectorsBySlice: FuncMap) => { [P in keyof FuncMap]: Parameters<FuncMap[P]> };
>sliceSelectors : Symbol(sliceSelectors, Decl(index.ts, 8, 30))
>FuncMap : Symbol(FuncMap, Decl(index.ts, 9, 21))
>SelectorMap : Symbol(SelectorMap, Decl(index.ts, 0, 0))
>FuncMap : Symbol(FuncMap, Decl(index.ts, 9, 21))
>selectorsBySlice : Symbol(selectorsBySlice, Decl(index.ts, 9, 59))
>FuncMap : Symbol(FuncMap, Decl(index.ts, 9, 21))
>P : Symbol(P, Decl(index.ts, 9, 92))
>FuncMap : Symbol(FuncMap, Decl(index.ts, 9, 21))
>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --))
>FuncMap : Symbol(FuncMap, Decl(index.ts, 9, 21))
>P : Symbol(P, Decl(index.ts, 9, 92))
};

View File

@ -0,0 +1,35 @@
=== tests/cases/compiler/types.ts ===
export type SelectorMap<T extends Record<string, (...params: unknown[]) => unknown>> = {
>SelectorMap : SelectorMap<T>
>params : unknown[]
[key in keyof T]: T[key];
};
=== tests/cases/compiler/index.ts ===
export type SelectorMap<T extends Record<string, (...params: unknown[]) => unknown>> = {
>SelectorMap : SelectorMap<T>
>params : unknown[]
[key in keyof T]: T[key];
};
export declare const value2: {
>value2 : { sliceSelectors: <FuncMap extends import("tests/cases/compiler/types").SelectorMap<FuncMap>>(selectorsBySlice: FuncMap) => { [P in keyof FuncMap]: Parameters<FuncMap[P]>; }; }
sliceSelectors: <FuncMap extends import('./types').SelectorMap<FuncMap>>(selectorsBySlice: FuncMap) => { [P in keyof FuncMap]: Parameters<FuncMap[P]> };
>sliceSelectors : <FuncMap extends import("tests/cases/compiler/types").SelectorMap<FuncMap>>(selectorsBySlice: FuncMap) => { [P in keyof FuncMap]: Parameters<FuncMap[P]>; }
>selectorsBySlice : FuncMap
};
export declare const value3: {
>value3 : { sliceSelectors: <FuncMap extends SelectorMap<FuncMap>>(selectorsBySlice: FuncMap) => { [P in keyof FuncMap]: Parameters<FuncMap[P]>; }; }
sliceSelectors: <FuncMap extends SelectorMap<FuncMap>>(selectorsBySlice: FuncMap) => { [P in keyof FuncMap]: Parameters<FuncMap[P]> };
>sliceSelectors : <FuncMap extends SelectorMap<FuncMap>>(selectorsBySlice: FuncMap) => { [P in keyof FuncMap]: Parameters<FuncMap[P]>; }
>selectorsBySlice : FuncMap
};

View File

@ -0,0 +1,20 @@
// @strict: true
// @filename: types.ts
export type SelectorMap<T extends Record<string, (...params: unknown[]) => unknown>> = {
[key in keyof T]: T[key];
};
// @filename: index.ts
export type SelectorMap<T extends Record<string, (...params: unknown[]) => unknown>> = {
[key in keyof T]: T[key];
};
export declare const value2: {
sliceSelectors: <FuncMap extends import('./types').SelectorMap<FuncMap>>(selectorsBySlice: FuncMap) => { [P in keyof FuncMap]: Parameters<FuncMap[P]> };
};
export declare const value3: {
sliceSelectors: <FuncMap extends SelectorMap<FuncMap>>(selectorsBySlice: FuncMap) => { [P in keyof FuncMap]: Parameters<FuncMap[P]> };
};

View File

@ -0,0 +1,38 @@
/// <reference path="fourslash.ts" />
// @filename: types.ts
//// /** @deprecated */
//// export type SelectorMap<T extends Record<string, (...params: unknown[]) => unknown>> = {
//// [key in keyof T]: T[key];
//// };
// @filename: index.ts
//// /** @deprecated */
//// export type SelectorMap<T extends Record<string, (...params: unknown[]) => unknown>> = {
//// [key in keyof T]: T[key];
//// };
////
//// export declare const value2: {
//// sliceSelectors: <FuncMap extends [|import('./types').SelectorMap<FuncMap>|]>(selectorsBySlice: FuncMap) => { [P in keyof FuncMap]: Parameters<FuncMap[P]> };
//// };
////
//// export declare const value3: {
//// sliceSelectors: <FuncMap extends [|SelectorMap<FuncMap>|]>(selectorsBySlice: FuncMap) => { [P in keyof FuncMap]: Parameters<FuncMap[P]> };
//// };
goTo.file("index.ts");
const ranges = test.ranges();
verify.getSuggestionDiagnostics([
{
"code": 6385,
"message": "'SelectorMap' is deprecated.",
"reportsDeprecated": true,
"range": ranges[0]
},
{
"code": 6385,
"message": "'SelectorMap' is deprecated.",
"reportsDeprecated": true,
"range": ranges[1]
},
]);