Skip to content

Commit f996402

Browse files
Allow extraction of type from type assertions for declaration emit
1 parent 297ba1b commit f996402

19 files changed

+499
-179
lines changed

src/compiler/transformers/declarations.ts

+214-51
Large diffs are not rendered by default.

src/compiler/transformers/declarations/diagnostics.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
DiagnosticMessage,
1111
Diagnostics,
1212
ElementAccessExpression,
13+
ExportAssignment,
1314
ExpressionWithTypeArguments,
1415
FunctionDeclaration,
1516
GetAccessorDeclaration,
@@ -24,6 +25,7 @@ import {
2425
isConstructorDeclaration,
2526
isConstructSignatureDeclaration,
2627
isElementAccessExpression,
28+
isExportAssignment,
2729
isExpressionWithTypeArguments,
2830
isFunctionDeclaration,
2931
isGetAccessor,
@@ -100,7 +102,8 @@ export type DeclarationDiagnosticProducing =
100102
| BinaryExpression
101103
| JSDocTypedefTag
102104
| JSDocCallbackTag
103-
| JSDocEnumTag;
105+
| JSDocEnumTag
106+
| ExportAssignment;
104107

105108
/** @internal */
106109
export function canProduceDiagnostics(node: Node): node is DeclarationDiagnosticProducing {
@@ -231,9 +234,18 @@ export function createGetSymbolAccessibilityDiagnosticForNode(node: DeclarationD
231234
else if (isTypeAliasDeclaration(node) || isJSDocTypeAlias(node)) {
232235
return getTypeAliasDeclarationVisibilityError;
233236
}
237+
else if (isExportAssignment(node)) {
238+
return getExportAssignmentTypeVisibilityDiagnosticMessage;
239+
}
234240
else {
235241
return Debug.assertNever(node, `Attempted to set a declaration diagnostic context for unhandled node kind: ${Debug.formatSyntaxKind((node as Node).kind)}`);
236242
}
243+
function getExportAssignmentTypeVisibilityDiagnosticMessage() {
244+
return {
245+
diagnosticMessage: Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0,
246+
errorNode: node,
247+
};
248+
}
237249

238250
function getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult: SymbolAccessibilityResult) {
239251
if (node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement) {
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
accessorDeclarationEmitVisibilityErrors.ts(2,18): error TS2304: Cannot find name 'DoesNotExist'.
2-
accessorDeclarationEmitVisibilityErrors.ts(2,18): error TS4106: Parameter 'arg' of accessor has or is using private name 'DoesNotExist'.
32

43

5-
==== accessorDeclarationEmitVisibilityErrors.ts (2 errors) ====
4+
==== accessorDeclarationEmitVisibilityErrors.ts (1 errors) ====
65
export class Q {
76
set bet(arg: DoesNotExist) {}
87
~~~~~~~~~~~~
98
!!! error TS2304: Cannot find name 'DoesNotExist'.
10-
~~~~~~~~~~~~
11-
!!! error TS4106: Parameter 'arg' of accessor has or is using private name 'DoesNotExist'.
129
}

tests/baselines/reference/accessorDeclarationEmitVisibilityErrors.js

+6
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,9 @@ export class Q {
99
export class Q {
1010
set bet(arg) { }
1111
}
12+
13+
14+
//// [accessorDeclarationEmitVisibilityErrors.d.ts]
15+
export declare class Q {
16+
set bet(arg: DoesNotExist);
17+
}

tests/baselines/reference/coAndContraVariantInferences.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ interface Action<TName extends string, TPayload> {
7070
name: TName;
7171
payload: TPayload;
7272
}
73-
declare const actionA: Action<"ACTION_A", string>;
74-
declare const actionB: Action<"ACTION_B", boolean>;
73+
declare const actionA: Action<'ACTION_A', string>;
74+
declare const actionB: Action<'ACTION_B', boolean>;
7575
declare function call<TName extends string, TPayload>(action: Action<TName, TPayload>, fn: (action: Action<TName, TPayload>) => any): void;
7676
declare const printFn: (action: typeof actionA | typeof actionB) => void;

tests/baselines/reference/duplicatePropertiesInTypeAssertions02.js

+1
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ var x = {};
1010
//// [duplicatePropertiesInTypeAssertions02.d.ts]
1111
declare let x: {
1212
a: number;
13+
a: number;
1314
};

tests/baselines/reference/hugeDeclarationOutputGetsTruncatedWithError.errors.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ hugeDeclarationOutputGetsTruncatedWithError.ts(5,14): error TS7056: The inferred
66

77
type manyprops = `${props}${props}`;
88

9-
export const c = null as any as {[K in manyprops]: {[K2 in manyprops]: `${K}.${K2}`}};
9+
export const c = () => null as any as {[K in manyprops]: {[K2 in manyprops]: `${K}.${K2}`}};
1010
~
1111
!!! error TS7056: The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed.

tests/baselines/reference/hugeDeclarationOutputGetsTruncatedWithError.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ type props = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "
55

66
type manyprops = `${props}${props}`;
77

8-
export const c = null as any as {[K in manyprops]: {[K2 in manyprops]: `${K}.${K2}`}};
8+
export const c = () => null as any as {[K in manyprops]: {[K2 in manyprops]: `${K}.${K2}`}};
99

1010
//// [hugeDeclarationOutputGetsTruncatedWithError.js]
1111
"use strict";
1212
Object.defineProperty(exports, "__esModule", { value: true });
1313
exports.c = void 0;
14-
exports.c = null;
14+
var c = function () { return null; };
15+
exports.c = c;

tests/baselines/reference/hugeDeclarationOutputGetsTruncatedWithError.symbols

+5-5
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ type manyprops = `${props}${props}`;
99
>props : Symbol(props, Decl(hugeDeclarationOutputGetsTruncatedWithError.ts, 0, 0))
1010
>props : Symbol(props, Decl(hugeDeclarationOutputGetsTruncatedWithError.ts, 0, 0))
1111

12-
export const c = null as any as {[K in manyprops]: {[K2 in manyprops]: `${K}.${K2}`}};
12+
export const c = () => null as any as {[K in manyprops]: {[K2 in manyprops]: `${K}.${K2}`}};
1313
>c : Symbol(c, Decl(hugeDeclarationOutputGetsTruncatedWithError.ts, 4, 12))
14-
>K : Symbol(K, Decl(hugeDeclarationOutputGetsTruncatedWithError.ts, 4, 34))
14+
>K : Symbol(K, Decl(hugeDeclarationOutputGetsTruncatedWithError.ts, 4, 40))
1515
>manyprops : Symbol(manyprops, Decl(hugeDeclarationOutputGetsTruncatedWithError.ts, 0, 167))
16-
>K2 : Symbol(K2, Decl(hugeDeclarationOutputGetsTruncatedWithError.ts, 4, 53))
16+
>K2 : Symbol(K2, Decl(hugeDeclarationOutputGetsTruncatedWithError.ts, 4, 59))
1717
>manyprops : Symbol(manyprops, Decl(hugeDeclarationOutputGetsTruncatedWithError.ts, 0, 167))
18-
>K : Symbol(K, Decl(hugeDeclarationOutputGetsTruncatedWithError.ts, 4, 34))
19-
>K2 : Symbol(K2, Decl(hugeDeclarationOutputGetsTruncatedWithError.ts, 4, 53))
18+
>K : Symbol(K, Decl(hugeDeclarationOutputGetsTruncatedWithError.ts, 4, 40))
19+
>K2 : Symbol(K2, Decl(hugeDeclarationOutputGetsTruncatedWithError.ts, 4, 59))
2020

tests/baselines/reference/hugeDeclarationOutputGetsTruncatedWithError.types

+3-2
Large diffs are not rendered by default.

tests/baselines/reference/namedTupleMembers.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ export declare const func: Func<SegmentAnnotated>;
133133
export declare function useState<T>(initial: T): [value: T, setter: (T: any) => void];
134134
export type Iter = Func<[step: number, iterations: number]>;
135135
export declare function readSegment([length, count]: [number, number]): void;
136-
export declare const val: [number, number];
136+
export declare const val: Parameters<typeof readSegment>[0];
137137
export type RecursiveTupleA = [initial: string, next: RecursiveTupleA];
138138
export type RecursiveTupleB = [first: string, ptr: RecursiveTupleB];
139139
export type RecusiveRest = [first: string, ...rest: RecusiveRest[]];

tests/baselines/reference/verbatim-declarations-assertions(strict=false).js

+40-55
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ export const vLiteral = null! as "1" | "1"
5353
type R = { foo: string }
5454

5555
export class C {
56+
// under !strictNullChecks all types can be reused from the assertion
57+
// under strictNullChecks we need to add undefined, and we can't always know we can
5658
// Can't know if references contain undefined, fall back to inference
5759
tsResolve? = null! as R | R;
5860
tsResolve2? = null! as R | R | string;
@@ -148,6 +150,8 @@ exports.vStringLiteral = null;
148150
exports.vLiteral = null;
149151
var C = /** @class */ (function () {
150152
function C() {
153+
// under !strictNullChecks all types can be reused from the assertion
154+
// under strictNullChecks we need to add undefined, and we can't always know we can
151155
// Can't know if references contain undefined, fall back to inference
152156
this.tsResolve = null;
153157
this.tsResolve2 = null;
@@ -168,75 +172,56 @@ exports.C = C;
168172

169173

170174
//// [assertToTypeReferences.d.ts]
171-
export declare let vLet: {
175+
type P = {} & {
172176
name: string;
173177
};
174-
export declare const vConst: {
175-
name: string;
176-
};
177-
export declare function fn(p?: {
178-
name: string;
179-
}): void;
180-
export declare function fnWithRequiredDefaultParam(p: {
181-
name: string;
182-
}, req: number): void;
178+
export declare let vLet: P;
179+
export declare const vConst: P;
180+
export declare function fn(p?: P): void;
181+
export declare function fnWithRequiredDefaultParam(p: P, req: number): void;
183182
export declare class C {
184-
ctorField: {
185-
name: string;
186-
};
187-
field: {
188-
name: string;
189-
};
190-
readonly roFiled: {
191-
name: string;
192-
};
193-
method(p?: {
194-
name: string;
195-
}): void;
196-
methodWithRequiredDefault(p: {
197-
name: string;
198-
}, req: number): void;
199-
methodWithRequiredDefault2(p: {
200-
name: string;
201-
}, req: number): void;
202-
constructor(ctorField?: {
203-
name: string;
204-
});
183+
ctorField: P;
184+
field: P;
185+
readonly roFiled: P;
186+
method(p?: P): void;
187+
methodWithRequiredDefault(p: P, req: number): void;
188+
methodWithRequiredDefault2(p: P, req: number): void;
189+
constructor(ctorField?: P);
205190
}
206191
declare const _default: {
207192
name: string;
208193
};
209194
export default _default;
210195
//// [assertToTypeLiteral.d.ts]
211-
export declare let vLet: {
196+
export declare let vLet: {} & {
212197
name: string;
213198
};
214-
export declare const vConst: {
199+
export declare const vConst: {} & {
215200
name: string;
216201
};
217-
export declare function fn(p?: {
202+
export declare function fn(p?: {} & {
218203
name: string;
219204
}): void;
220-
export declare function fnWithRequiredDefaultParam(p: {
205+
export declare function fnWithRequiredDefaultParam(p: {} & {
221206
name: string;
222207
}, req: number): void;
223208
export declare class C {
224-
ctorField: {
209+
ctorField: {} & {
225210
name: string;
226211
};
227-
field: {
212+
field: {} & {
228213
name: string;
229214
};
230-
readonly roFiled: {
215+
readonly roFiled: {} & {
231216
name: string;
232217
};
233-
method(p?: {
218+
method(p?: {} & {
234219
name: string;
235220
}): void;
236-
methodWithRequiredDefault(p: {
221+
methodWithRequiredDefault(p: {} & {
237222
name: string;
238223
}, req: number): void;
239-
constructor(ctorField?: {
224+
constructor(ctorField?: {} & {
240225
name: string;
241226
});
242227
get x(): {
@@ -251,23 +236,23 @@ declare const _default: {
251236
};
252237
export default _default;
253238
//// [assertToOtherTypes.d.ts]
254-
export declare const vNumberLiteral: 1;
255-
export declare const vStringLiteral: "1";
256-
export declare const vLiteral: "1";
239+
export declare const vNumberLiteral: 1 | 1;
240+
export declare const vStringLiteral: "1" | "1";
241+
export declare const vLiteral: "1" | "1";
257242
type R = {
258243
foo: string;
259244
};
260245
export declare class C {
261-
tsResolve?: R;
262-
tsResolve2?: string | R;
263-
reuseType?: string | ((p: R) => void);
264-
reuseType2?: string | (new (p: R) => R);
265-
reuseType3?: any;
266-
reuseType4?: [R, R, R];
267-
reuseType5?: R[];
268-
reuseType6?: 1 | "2" | 1n;
269-
reuseType7?: "A";
270-
reuseType8?: `${string}-ok`;
271-
reuseType9?: this;
246+
tsResolve?: R | R;
247+
tsResolve2?: R | R | string;
248+
reuseType?: ((p: R) => void) | string | string;
249+
reuseType2?: (new (p: R) => R) | string | string;
250+
reuseType3?: string | number | bigint | symbol | unknown | any | never | symbol;
251+
reuseType4?: [R, R, R] | [R, R, R];
252+
reuseType5?: R[] | R[];
253+
reuseType6?: 1 | "2" | 1n | 1n;
254+
reuseType7?: `A` | `A`;
255+
reuseType8?: `${string}-ok` | `${string}-ok`;
256+
reuseType9?: this | this;
272257
}
273258
export {};

tests/baselines/reference/verbatim-declarations-assertions(strict=false).symbols

+14-12
Original file line numberDiff line numberDiff line change
@@ -136,34 +136,36 @@ type R = { foo: string }
136136
export class C {
137137
>C : Symbol(C, Decl(assertToOtherTypes.ts, 4, 24))
138138

139+
// under !strictNullChecks all types can be reused from the assertion
140+
// under strictNullChecks we need to add undefined, and we can't always know we can
139141
// Can't know if references contain undefined, fall back to inference
140142
tsResolve? = null! as R | R;
141143
>tsResolve : Symbol(C.tsResolve, Decl(assertToOtherTypes.ts, 6, 16))
142144
>R : Symbol(R, Decl(assertToOtherTypes.ts, 2, 42))
143145
>R : Symbol(R, Decl(assertToOtherTypes.ts, 2, 42))
144146

145147
tsResolve2? = null! as R | R | string;
146-
>tsResolve2 : Symbol(C.tsResolve2, Decl(assertToOtherTypes.ts, 8, 32))
148+
>tsResolve2 : Symbol(C.tsResolve2, Decl(assertToOtherTypes.ts, 10, 32))
147149
>R : Symbol(R, Decl(assertToOtherTypes.ts, 2, 42))
148150
>R : Symbol(R, Decl(assertToOtherTypes.ts, 2, 42))
149151

150152
// Simple type. we can add undefined
151153
reuseType? = null! as ((p: R) => void) | string | string;
152-
>reuseType : Symbol(C.reuseType, Decl(assertToOtherTypes.ts, 9, 42))
153-
>p : Symbol(p, Decl(assertToOtherTypes.ts, 11, 28))
154+
>reuseType : Symbol(C.reuseType, Decl(assertToOtherTypes.ts, 11, 42))
155+
>p : Symbol(p, Decl(assertToOtherTypes.ts, 13, 28))
154156
>R : Symbol(R, Decl(assertToOtherTypes.ts, 2, 42))
155157

156158
reuseType2? = null! as (new (p: R) => R) | string | string;
157-
>reuseType2 : Symbol(C.reuseType2, Decl(assertToOtherTypes.ts, 11, 61))
158-
>p : Symbol(p, Decl(assertToOtherTypes.ts, 12, 33))
159+
>reuseType2 : Symbol(C.reuseType2, Decl(assertToOtherTypes.ts, 13, 61))
160+
>p : Symbol(p, Decl(assertToOtherTypes.ts, 14, 33))
159161
>R : Symbol(R, Decl(assertToOtherTypes.ts, 2, 42))
160162
>R : Symbol(R, Decl(assertToOtherTypes.ts, 2, 42))
161163

162164
reuseType3? = null! as string | number | bigint | symbol | unknown | any | never | symbol;
163-
>reuseType3 : Symbol(C.reuseType3, Decl(assertToOtherTypes.ts, 12, 63))
165+
>reuseType3 : Symbol(C.reuseType3, Decl(assertToOtherTypes.ts, 14, 63))
164166

165167
reuseType4? = null! as [R, R, R] | [R, R, R];
166-
>reuseType4 : Symbol(C.reuseType4, Decl(assertToOtherTypes.ts, 13, 94))
168+
>reuseType4 : Symbol(C.reuseType4, Decl(assertToOtherTypes.ts, 15, 94))
167169
>R : Symbol(R, Decl(assertToOtherTypes.ts, 2, 42))
168170
>R : Symbol(R, Decl(assertToOtherTypes.ts, 2, 42))
169171
>R : Symbol(R, Decl(assertToOtherTypes.ts, 2, 42))
@@ -172,19 +174,19 @@ export class C {
172174
>R : Symbol(R, Decl(assertToOtherTypes.ts, 2, 42))
173175

174176
reuseType5? = null! as R[] | R[];
175-
>reuseType5 : Symbol(C.reuseType5, Decl(assertToOtherTypes.ts, 14, 49))
177+
>reuseType5 : Symbol(C.reuseType5, Decl(assertToOtherTypes.ts, 16, 49))
176178
>R : Symbol(R, Decl(assertToOtherTypes.ts, 2, 42))
177179
>R : Symbol(R, Decl(assertToOtherTypes.ts, 2, 42))
178180

179181
reuseType6? = null! as 1 | "2" | 1n | 1n;
180-
>reuseType6 : Symbol(C.reuseType6, Decl(assertToOtherTypes.ts, 15, 37))
182+
>reuseType6 : Symbol(C.reuseType6, Decl(assertToOtherTypes.ts, 17, 37))
181183

182184
reuseType7? = null! as `A` | `A`;
183-
>reuseType7 : Symbol(C.reuseType7, Decl(assertToOtherTypes.ts, 16, 45))
185+
>reuseType7 : Symbol(C.reuseType7, Decl(assertToOtherTypes.ts, 18, 45))
184186

185187
reuseType8? = null! as `${string}-ok` | `${string}-ok`;
186-
>reuseType8 : Symbol(C.reuseType8, Decl(assertToOtherTypes.ts, 17, 37))
188+
>reuseType8 : Symbol(C.reuseType8, Decl(assertToOtherTypes.ts, 19, 37))
187189

188190
reuseType9? = null! as this | this;
189-
>reuseType9 : Symbol(C.reuseType9, Decl(assertToOtherTypes.ts, 18, 59))
191+
>reuseType9 : Symbol(C.reuseType9, Decl(assertToOtherTypes.ts, 20, 59))
190192
}

tests/baselines/reference/verbatim-declarations-assertions(strict=false).types

+2
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ type R = { foo: string }
175175
export class C {
176176
>C : C
177177

178+
// under !strictNullChecks all types can be reused from the assertion
179+
// under strictNullChecks we need to add undefined, and we can't always know we can
178180
// Can't know if references contain undefined, fall back to inference
179181
tsResolve? = null! as R | R;
180182
>tsResolve : R

0 commit comments

Comments
 (0)