Skip to content

Commit 2f626bf

Browse files
authored
Elaborate errors on const asserted expressions (#54396)
1 parent f5ab714 commit 2f626bf

File tree

6 files changed

+107
-5
lines changed

6 files changed

+107
-5
lines changed

src/compiler/checker.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
arrayToMultiMap,
2525
ArrayTypeNode,
2626
ArrowFunction,
27+
AsExpression,
2728
AssertionExpression,
2829
AssignmentDeclarationKind,
2930
AssignmentKind,
@@ -19350,9 +19351,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1935019351
return true;
1935119352
}
1935219353
switch (node.kind) {
19354+
case SyntaxKind.AsExpression:
19355+
if (!isConstAssertion(node)) {
19356+
break;
19357+
}
19358+
// fallthrough
1935319359
case SyntaxKind.JsxExpression:
1935419360
case SyntaxKind.ParenthesizedExpression:
19355-
return elaborateError((node as ParenthesizedExpression | JsxExpression).expression, source, target, relation, headMessage, containingMessageChain, errorOutputContainer);
19361+
return elaborateError((node as AsExpression | ParenthesizedExpression | JsxExpression).expression, source, target, relation, headMessage, containingMessageChain, errorOutputContainer);
1935619362
case SyntaxKind.BinaryExpression:
1935719363
switch ((node as BinaryExpression).operatorToken.kind) {
1935819364
case SyntaxKind.EqualsToken:

tests/baselines/reference/constAssertions.errors.txt

+18-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ tests/cases/conformance/expressions/typeAssertions/constAssertions.ts(44,32): er
22
tests/cases/conformance/expressions/typeAssertions/constAssertions.ts(61,10): error TS1355: A 'const' assertions can only be applied to references to enum members, or string, number, boolean, array, or object literals.
33
tests/cases/conformance/expressions/typeAssertions/constAssertions.ts(62,10): error TS1355: A 'const' assertions can only be applied to references to enum members, or string, number, boolean, array, or object literals.
44
tests/cases/conformance/expressions/typeAssertions/constAssertions.ts(63,10): error TS1355: A 'const' assertions can only be applied to references to enum members, or string, number, boolean, array, or object literals.
5+
tests/cases/conformance/expressions/typeAssertions/constAssertions.ts(118,3): error TS2322: Type '3' is not assignable to type '2'.
56

67

7-
==== tests/cases/conformance/expressions/typeAssertions/constAssertions.ts (4 errors) ====
8+
==== tests/cases/conformance/expressions/typeAssertions/constAssertions.ts (5 errors) ====
89
let v1 = 'abc' as const;
910
let v2 = `abc` as const;
1011
let v3 = 10 as const;
@@ -120,4 +121,19 @@ tests/cases/conformance/expressions/typeAssertions/constAssertions.ts(63,10): er
120121
return [`get-${propName}`, `set-${propName}`] as const;
121122
}
122123

123-
const ns1 = accessorNames('foo');
124+
const ns1 = accessorNames('foo');
125+
126+
// repro from https://github.com/microsoft/TypeScript/issues/54374
127+
interface Foo54374 {
128+
a: 1;
129+
b: 2;
130+
}
131+
132+
const fooConst54374: Foo54374 = {
133+
a: 1,
134+
b: 3
135+
~
136+
!!! error TS2322: Type '3' is not assignable to type '2'.
137+
!!! related TS6500 tests/cases/conformance/expressions/typeAssertions/constAssertions.ts:113:3: The expected type comes from property 'b' which is declared here on type 'Foo54374'
138+
} as const
139+

tests/baselines/reference/constAssertions.js

+22-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,19 @@ function accessorNames<S extends string>(propName: S) {
106106
return [`get-${propName}`, `set-${propName}`] as const;
107107
}
108108

109-
const ns1 = accessorNames('foo');
109+
const ns1 = accessorNames('foo');
110+
111+
// repro from https://github.com/microsoft/TypeScript/issues/54374
112+
interface Foo54374 {
113+
a: 1;
114+
b: 2;
115+
}
116+
117+
const fooConst54374: Foo54374 = {
118+
a: 1,
119+
b: 3
120+
} as const
121+
110122

111123
//// [constAssertions.js]
112124
"use strict";
@@ -193,6 +205,10 @@ function accessorNames(propName) {
193205
return [`get-${propName}`, `set-${propName}`];
194206
}
195207
const ns1 = accessorNames('foo');
208+
const fooConst54374 = {
209+
a: 1,
210+
b: 3
211+
};
196212

197213

198214
//// [constAssertions.d.ts]
@@ -311,3 +327,8 @@ declare function ff4(verify: boolean, contentMatches: boolean): "verify_match" |
311327
declare function ff5(verify: boolean, contentMatches: boolean): "verify_match" | "verify_nonMatch" | "write_match" | "write_nonMatch";
312328
declare function accessorNames<S extends string>(propName: S): readonly [`get-${S}`, `set-${S}`];
313329
declare const ns1: readonly ["get-foo", "set-foo"];
330+
interface Foo54374 {
331+
a: 1;
332+
b: 2;
333+
}
334+
declare const fooConst54374: Foo54374;

tests/baselines/reference/constAssertions.symbols

+24
Original file line numberDiff line numberDiff line change
@@ -387,3 +387,27 @@ const ns1 = accessorNames('foo');
387387
>ns1 : Symbol(ns1, Decl(constAssertions.ts, 107, 5))
388388
>accessorNames : Symbol(accessorNames, Decl(constAssertions.ts, 101, 1))
389389

390+
// repro from https://github.com/microsoft/TypeScript/issues/54374
391+
interface Foo54374 {
392+
>Foo54374 : Symbol(Foo54374, Decl(constAssertions.ts, 107, 33))
393+
394+
a: 1;
395+
>a : Symbol(Foo54374.a, Decl(constAssertions.ts, 110, 20))
396+
397+
b: 2;
398+
>b : Symbol(Foo54374.b, Decl(constAssertions.ts, 111, 7))
399+
}
400+
401+
const fooConst54374: Foo54374 = {
402+
>fooConst54374 : Symbol(fooConst54374, Decl(constAssertions.ts, 115, 5))
403+
>Foo54374 : Symbol(Foo54374, Decl(constAssertions.ts, 107, 33))
404+
405+
a: 1,
406+
>a : Symbol(a, Decl(constAssertions.ts, 115, 33))
407+
408+
b: 3
409+
>b : Symbol(b, Decl(constAssertions.ts, 116, 7))
410+
411+
} as const
412+
>const : Symbol(const)
413+

tests/baselines/reference/constAssertions.types

+24
Original file line numberDiff line numberDiff line change
@@ -540,3 +540,27 @@ const ns1 = accessorNames('foo');
540540
>accessorNames : <S extends string>(propName: S) => readonly [`get-${S}`, `set-${S}`]
541541
>'foo' : "foo"
542542

543+
// repro from https://github.com/microsoft/TypeScript/issues/54374
544+
interface Foo54374 {
545+
a: 1;
546+
>a : 1
547+
548+
b: 2;
549+
>b : 2
550+
}
551+
552+
const fooConst54374: Foo54374 = {
553+
>fooConst54374 : Foo54374
554+
>{ a: 1, b: 3} as const : { readonly a: 1; readonly b: 3; }
555+
>{ a: 1, b: 3} : { readonly a: 1; readonly b: 3; }
556+
557+
a: 1,
558+
>a : 1
559+
>1 : 1
560+
561+
b: 3
562+
>b : 3
563+
>3 : 3
564+
565+
} as const
566+

tests/cases/conformance/expressions/typeAssertions/constAssertions.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,15 @@ function accessorNames<S extends string>(propName: S) {
109109
return [`get-${propName}`, `set-${propName}`] as const;
110110
}
111111

112-
const ns1 = accessorNames('foo');
112+
const ns1 = accessorNames('foo');
113+
114+
// repro from https://github.com/microsoft/TypeScript/issues/54374
115+
interface Foo54374 {
116+
a: 1;
117+
b: 2;
118+
}
119+
120+
const fooConst54374: Foo54374 = {
121+
a: 1,
122+
b: 3
123+
} as const

0 commit comments

Comments
 (0)