mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-04-17 01:49:41 -05:00
Error if type node uses inaccessible type in isolated declarations (#58620)
This commit is contained in:
committed by
GitHub
parent
f2aebff7a3
commit
8537bb72eb
@@ -6085,6 +6085,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
context.tracker.reportInferenceFallback(existing);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -8301,6 +8302,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// If the symbol is found both in declaration scope and in current scope then it shoudl point to the same reference
|
||||
(symAtLocation && sym && !getSymbolIfSameReference(getExportSymbolOfValueSymbolIfExported(symAtLocation), sym))
|
||||
) {
|
||||
// In isolated declaration we will not do rest parameter expansion so there is no need to report on these.
|
||||
if (symAtLocation !== unknownSymbol) {
|
||||
context.tracker.reportInferenceFallback(node);
|
||||
}
|
||||
introducesError = true;
|
||||
return { introducesError, node, sym };
|
||||
}
|
||||
@@ -8321,6 +8326,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
!isDeclarationName(node) &&
|
||||
isSymbolAccessible(sym, context.enclosingDeclaration, meaning, /*shouldComputeAliasesToMakeVisible*/ false).accessibility !== SymbolAccessibility.Accessible
|
||||
) {
|
||||
context.tracker.reportInferenceFallback(node);
|
||||
introducesError = true;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -7018,6 +7018,10 @@
|
||||
"category": "Error",
|
||||
"code": 9038
|
||||
},
|
||||
"Type containing private name '{0}' can't be used with --isolatedDeclarations.": {
|
||||
"category": "Error",
|
||||
"code": 9039
|
||||
},
|
||||
"JSX attributes must only be assigned a non-empty 'expression'.": {
|
||||
"category": "Error",
|
||||
"code": 17000
|
||||
|
||||
@@ -19,12 +19,14 @@ import {
|
||||
DiagnosticWithLocation,
|
||||
ElementAccessExpression,
|
||||
EmitResolver,
|
||||
EntityNameOrEntityNameExpression,
|
||||
ExportAssignment,
|
||||
Expression,
|
||||
ExpressionWithTypeArguments,
|
||||
findAncestor,
|
||||
FunctionDeclaration,
|
||||
FunctionExpression,
|
||||
FunctionLikeDeclaration,
|
||||
GetAccessorDeclaration,
|
||||
getAllAccessorDeclarations,
|
||||
getNameOfDeclaration,
|
||||
@@ -40,9 +42,12 @@ import {
|
||||
isConstructorDeclaration,
|
||||
isConstructSignatureDeclaration,
|
||||
isElementAccessExpression,
|
||||
isEntityName,
|
||||
isEntityNameExpression,
|
||||
isExportAssignment,
|
||||
isExpressionWithTypeArguments,
|
||||
isFunctionDeclaration,
|
||||
isFunctionLikeDeclaration,
|
||||
isGetAccessor,
|
||||
isHeritageClause,
|
||||
isImportEqualsDeclaration,
|
||||
@@ -53,15 +58,18 @@ import {
|
||||
isParameter,
|
||||
isParameterPropertyDeclaration,
|
||||
isParenthesizedExpression,
|
||||
isPartOfTypeNode,
|
||||
isPropertyAccessExpression,
|
||||
isPropertyDeclaration,
|
||||
isPropertySignature,
|
||||
isReturnStatement,
|
||||
isSetAccessor,
|
||||
isStatement,
|
||||
isStatic,
|
||||
isTypeAliasDeclaration,
|
||||
isTypeAssertionExpression,
|
||||
isTypeParameterDeclaration,
|
||||
isTypeQueryNode,
|
||||
isVariableDeclaration,
|
||||
JSDocCallbackTag,
|
||||
JSDocEnumTag,
|
||||
@@ -658,6 +666,9 @@ export function createGetIsolatedDeclarationErrors(resolver: EmitResolver) {
|
||||
if (heritageClause) {
|
||||
return createDiagnosticForNode(node, Diagnostics.Extends_clause_can_t_contain_an_expression_with_isolatedDeclarations);
|
||||
}
|
||||
if ((isPartOfTypeNode(node) || isTypeQueryNode(node.parent)) && (isEntityName(node) || isEntityNameExpression(node))) {
|
||||
return createEntityInTypeNodeError(node);
|
||||
}
|
||||
Debug.type<WithIsolatedDeclarationDiagnostic>(node);
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.GetAccessor:
|
||||
@@ -694,8 +705,15 @@ export function createGetIsolatedDeclarationErrors(resolver: EmitResolver) {
|
||||
}
|
||||
|
||||
function findNearestDeclaration(node: Node) {
|
||||
const result = findAncestor(node, n => isExportAssignment(n) || (isStatement(n) ? "quit" : isVariableDeclaration(n) || isPropertyDeclaration(n) || isParameter(n)));
|
||||
return result as VariableDeclaration | PropertyDeclaration | ParameterDeclaration | ExportAssignment | undefined;
|
||||
const result = findAncestor(node, n => isExportAssignment(n) || isStatement(n) || isVariableDeclaration(n) || isPropertyDeclaration(n) || isParameter(n));
|
||||
if (!result) return undefined;
|
||||
|
||||
if (isExportAssignment(result)) return result;
|
||||
|
||||
if (isReturnStatement(result)) {
|
||||
return findAncestor(result, (n): n is Exclude<FunctionLikeDeclaration, ConstructorDeclaration> => isFunctionLikeDeclaration(n) && !isConstructorDeclaration(n));
|
||||
}
|
||||
return (isStatement(result) ? undefined : result) as VariableDeclaration | PropertyDeclaration | ParameterDeclaration | ExportAssignment | undefined;
|
||||
}
|
||||
|
||||
function createAccessorTypeError(node: GetAccessorDeclaration | SetAccessorDeclaration) {
|
||||
@@ -712,31 +730,27 @@ export function createGetIsolatedDeclarationErrors(resolver: EmitResolver) {
|
||||
}
|
||||
return diag;
|
||||
}
|
||||
function createObjectLiteralError(node: ShorthandPropertyAssignment | SpreadAssignment | ComputedPropertyName) {
|
||||
const diag = createDiagnosticForNode(node, errorByDeclarationKind[node.kind]);
|
||||
function addParentDeclarationRelatedInfo(node: Node, diag: DiagnosticWithLocation) {
|
||||
const parentDeclaration = findNearestDeclaration(node);
|
||||
if (parentDeclaration) {
|
||||
const targetStr = isExportAssignment(parentDeclaration) ? "" : getTextOfNode(parentDeclaration.name, /*includeTrivia*/ false);
|
||||
const targetStr = isExportAssignment(parentDeclaration) || !parentDeclaration.name ? "" : getTextOfNode(parentDeclaration.name, /*includeTrivia*/ false);
|
||||
addRelatedInfo(diag, createDiagnosticForNode(parentDeclaration, relatedSuggestionByDeclarationKind[parentDeclaration.kind], targetStr));
|
||||
}
|
||||
return diag;
|
||||
}
|
||||
function createObjectLiteralError(node: ShorthandPropertyAssignment | SpreadAssignment | ComputedPropertyName) {
|
||||
const diag = createDiagnosticForNode(node, errorByDeclarationKind[node.kind]);
|
||||
addParentDeclarationRelatedInfo(node, diag);
|
||||
return diag;
|
||||
}
|
||||
function createArrayLiteralError(node: ArrayLiteralExpression | SpreadElement) {
|
||||
const diag = createDiagnosticForNode(node, errorByDeclarationKind[node.kind]);
|
||||
const parentDeclaration = findNearestDeclaration(node);
|
||||
if (parentDeclaration) {
|
||||
const targetStr = isExportAssignment(parentDeclaration) ? "" : getTextOfNode(parentDeclaration.name, /*includeTrivia*/ false);
|
||||
addRelatedInfo(diag, createDiagnosticForNode(parentDeclaration, relatedSuggestionByDeclarationKind[parentDeclaration.kind], targetStr));
|
||||
}
|
||||
addParentDeclarationRelatedInfo(node, diag);
|
||||
return diag;
|
||||
}
|
||||
function createReturnTypeError(node: FunctionDeclaration | FunctionExpression | ArrowFunction | MethodDeclaration | ConstructSignatureDeclaration) {
|
||||
const diag = createDiagnosticForNode(node, errorByDeclarationKind[node.kind]);
|
||||
const parentDeclaration = findNearestDeclaration(node);
|
||||
if (parentDeclaration) {
|
||||
const targetStr = isExportAssignment(parentDeclaration) ? "" : getTextOfNode(parentDeclaration.name, /*includeTrivia*/ false);
|
||||
addRelatedInfo(diag, createDiagnosticForNode(parentDeclaration, relatedSuggestionByDeclarationKind[parentDeclaration.kind], targetStr));
|
||||
}
|
||||
addParentDeclarationRelatedInfo(node, diag);
|
||||
addRelatedInfo(diag, createDiagnosticForNode(node, relatedSuggestionByDeclarationKind[node.kind]));
|
||||
return diag;
|
||||
}
|
||||
@@ -768,12 +782,18 @@ export function createGetIsolatedDeclarationErrors(resolver: EmitResolver) {
|
||||
function createClassExpressionError(node: Expression) {
|
||||
return createExpressionError(node, Diagnostics.Inference_from_class_expressions_is_not_supported_with_isolatedDeclarations);
|
||||
}
|
||||
function createEntityInTypeNodeError(node: EntityNameOrEntityNameExpression) {
|
||||
const diag = createDiagnosticForNode(node, Diagnostics.Type_containing_private_name_0_can_t_be_used_with_isolatedDeclarations, getTextOfNode(node, /*includeTrivia*/ false));
|
||||
addParentDeclarationRelatedInfo(node, diag);
|
||||
return diag;
|
||||
}
|
||||
function createExpressionError(node: Expression, diagnosticMessage?: DiagnosticMessage) {
|
||||
const parentDeclaration = findNearestDeclaration(node);
|
||||
let diag: DiagnosticWithLocation;
|
||||
if (parentDeclaration) {
|
||||
const targetStr = isExportAssignment(parentDeclaration) ? "" : getTextOfNode(parentDeclaration.name, /*includeTrivia*/ false);
|
||||
const targetStr = isExportAssignment(parentDeclaration) || !parentDeclaration.name ? "" : getTextOfNode(parentDeclaration.name, /*includeTrivia*/ false);
|
||||
const parent = findAncestor(node.parent, n => isExportAssignment(n) || (isStatement(n) ? "quit" : !isParenthesizedExpression(n) && !isTypeAssertionExpression(n) && !isAsExpression(n)));
|
||||
|
||||
if (parentDeclaration === parent) {
|
||||
diag = createDiagnosticForNode(node, diagnosticMessage ?? errorByDeclarationKind[parentDeclaration.kind]);
|
||||
addRelatedInfo(diag, createDiagnosticForNode(parentDeclaration, relatedSuggestionByDeclarationKind[parentDeclaration.kind], targetStr));
|
||||
|
||||
@@ -65,6 +65,7 @@ import {
|
||||
isSpreadAssignment,
|
||||
isSpreadElement,
|
||||
isStatement,
|
||||
isTypeNode,
|
||||
isValueSignatureDeclaration,
|
||||
isVariableDeclaration,
|
||||
ModifierFlags,
|
||||
@@ -132,6 +133,7 @@ const errorCodes = [
|
||||
Diagnostics.Only_const_arrays_can_be_inferred_with_isolatedDeclarations.code,
|
||||
Diagnostics.Assigning_properties_to_functions_without_declaring_them_is_not_supported_with_isolatedDeclarations_Add_an_explicit_declaration_for_the_properties_assigned_to_this_function.code,
|
||||
Diagnostics.Declaration_emit_for_this_parameter_requires_implicitly_adding_undefined_to_it_s_type_This_is_not_supported_with_isolatedDeclarations.code,
|
||||
Diagnostics.Type_containing_private_name_0_can_t_be_used_with_isolatedDeclarations.code,
|
||||
Diagnostics.Add_satisfies_and_a_type_assertion_to_this_expression_satisfies_T_as_T_to_make_the_type_explicit.code,
|
||||
];
|
||||
|
||||
@@ -352,7 +354,7 @@ function withContext<T>(
|
||||
return undefined;
|
||||
}
|
||||
// No support for typeof in extends clauses
|
||||
if (isExpressionTarget && findAncestor(targetNode, isHeritageClause)) {
|
||||
if (isExpressionTarget && (findAncestor(targetNode, isHeritageClause) || findAncestor(targetNode, isTypeNode))) {
|
||||
return undefined;
|
||||
}
|
||||
// Can't inline type spread elements. Whatever you do isolated declarations will not infer from them
|
||||
|
||||
49
tests/baselines/reference/transpile/declarationNotInScopeTypes.d.ts
vendored
Normal file
49
tests/baselines/reference/transpile/declarationNotInScopeTypes.d.ts
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
//// [variables.ts] ////
|
||||
const x = "";
|
||||
export function one() {
|
||||
return {} as typeof x;
|
||||
}
|
||||
|
||||
export function two() {
|
||||
const y = "";
|
||||
return {} as typeof y;
|
||||
}
|
||||
|
||||
export function three() {
|
||||
type Z = string;
|
||||
return {} as Z;
|
||||
}
|
||||
//// [variables.d.ts] ////
|
||||
declare const x = "";
|
||||
export declare function one(): typeof x;
|
||||
export declare function two(): "";
|
||||
export declare function three(): string;
|
||||
export {};
|
||||
|
||||
|
||||
//// [Diagnostics reported]
|
||||
variables.ts(8,25): error TS9039: Type containing private name 'y' can't be used with --isolatedDeclarations.
|
||||
variables.ts(13,18): error TS9039: Type containing private name 'Z' can't be used with --isolatedDeclarations.
|
||||
|
||||
|
||||
==== variables.ts (2 errors) ====
|
||||
const x = "";
|
||||
export function one() {
|
||||
return {} as typeof x;
|
||||
}
|
||||
|
||||
export function two() {
|
||||
const y = "";
|
||||
return {} as typeof y;
|
||||
~
|
||||
!!! error TS9039: Type containing private name 'y' can't be used with --isolatedDeclarations.
|
||||
!!! related TS9031 variables.ts:6:17: Add a return type to the function declaration.
|
||||
}
|
||||
|
||||
export function three() {
|
||||
type Z = string;
|
||||
return {} as Z;
|
||||
~
|
||||
!!! error TS9039: Type containing private name 'Z' can't be used with --isolatedDeclarations.
|
||||
!!! related TS9031 variables.ts:11:17: Add a return type to the function declaration.
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
//// [variables.ts] ////
|
||||
const x = "";
|
||||
export function one() {
|
||||
return {} as typeof x;
|
||||
}
|
||||
|
||||
export function two() {
|
||||
const y = "";
|
||||
return {} as typeof y;
|
||||
}
|
||||
|
||||
export function three() {
|
||||
type Z = string;
|
||||
return {} as Z;
|
||||
}
|
||||
//// [variables.js] ////
|
||||
const x = "";
|
||||
export function one() {
|
||||
return {};
|
||||
}
|
||||
export function two() {
|
||||
const y = "";
|
||||
return {};
|
||||
}
|
||||
export function three() {
|
||||
return {};
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// @isolatedDeclarations: true
|
||||
// @declaration: true
|
||||
// @moduleResolution: node
|
||||
// @target: es2018
|
||||
// @jsx: react-jsx
|
||||
|
||||
////export function two() {
|
||||
//// const y = "";
|
||||
//// return {} as typeof y;
|
||||
////}
|
||||
////
|
||||
////export function three() {
|
||||
//// type Z = string;
|
||||
//// return {} as Z;
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: "Add return type '\"\"'",
|
||||
index: 0,
|
||||
newFileContent:
|
||||
`export function two(): "" {
|
||||
const y = "";
|
||||
return {} as typeof y;
|
||||
}
|
||||
|
||||
export function three() {
|
||||
type Z = string;
|
||||
return {} as Z;
|
||||
}`,
|
||||
});
|
||||
|
||||
|
||||
verify.codeFix({
|
||||
description: "Add return type 'string'",
|
||||
index: 1,
|
||||
newFileContent:
|
||||
`export function two() {
|
||||
const y = "";
|
||||
return {} as typeof y;
|
||||
}
|
||||
|
||||
export function three(): string {
|
||||
type Z = string;
|
||||
return {} as Z;
|
||||
}`,
|
||||
});
|
||||
17
tests/cases/transpile/declarationNotInScopeTypes.ts
Normal file
17
tests/cases/transpile/declarationNotInScopeTypes.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
// @declaration: true
|
||||
// @target: es6
|
||||
// @filename: variables.ts
|
||||
const x = "";
|
||||
export function one() {
|
||||
return {} as typeof x;
|
||||
}
|
||||
|
||||
export function two() {
|
||||
const y = "";
|
||||
return {} as typeof y;
|
||||
}
|
||||
|
||||
export function three() {
|
||||
type Z = string;
|
||||
return {} as Z;
|
||||
}
|
||||
Reference in New Issue
Block a user