Skip to content

Commit 95cc1c2

Browse files
authored
Fix crash from missing valueDeclaration on intersection property (microsoft#37696)
* Add crashing test * Fix missing valueDeclaration on intersection symbol property * Remove assertion from serializeAsClass
1 parent 4a646c9 commit 95cc1c2

File tree

4 files changed

+94
-7
lines changed

4 files changed

+94
-7
lines changed

src/compiler/checker.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6211,14 +6211,18 @@ namespace ts {
62116211
];
62126212
const symbolProps = getPropertiesOfType(classType);
62136213
const publicSymbolProps = filter(symbolProps, s => {
6214+
// `valueDeclaration` could be undefined if inherited from
6215+
// a union/intersection base type, but inherited properties
6216+
// don't matter here.
62146217
const valueDecl = s.valueDeclaration;
6215-
Debug.assertIsDefined(valueDecl);
6216-
return !(isNamedDeclaration(valueDecl) && isPrivateIdentifier(valueDecl.name));
6218+
return valueDecl && !(isNamedDeclaration(valueDecl) && isPrivateIdentifier(valueDecl.name));
62176219
});
62186220
const hasPrivateIdentifier = some(symbolProps, s => {
6221+
// `valueDeclaration` could be undefined if inherited from
6222+
// a union/intersection base type, but inherited properties
6223+
// don't matter here.
62196224
const valueDecl = s.valueDeclaration;
6220-
Debug.assertIsDefined(valueDecl);
6221-
return isNamedDeclaration(valueDecl) && isPrivateIdentifier(valueDecl.name);
6225+
return valueDecl && isNamedDeclaration(valueDecl) && isPrivateIdentifier(valueDecl.name);
62226226
});
62236227
// Boil down all private properties into a single one.
62246228
const privateProperties = hasPrivateIdentifier ?
@@ -10420,7 +10424,7 @@ namespace ts {
1042010424
if (!firstValueDeclaration) {
1042110425
firstValueDeclaration = prop.valueDeclaration;
1042210426
}
10423-
else if (prop.valueDeclaration !== firstValueDeclaration) {
10427+
else if (prop.valueDeclaration && prop.valueDeclaration !== firstValueDeclaration) {
1042410428
hasNonUniformValueDeclaration = true;
1042510429
}
1042610430
declarations = addRange(declarations, prop.declarations);
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//// [tests/cases/compiler/jsEmitIntersectionProperty.ts] ////
2+
3+
//// [globals.d.ts]
4+
// #37015 - test asserts lack of crash
5+
6+
7+
8+
declare class CoreObject {
9+
static extend<
10+
Statics,
11+
Instance extends B1,
12+
T1,
13+
B1
14+
>(
15+
this: Statics & { new(): Instance },
16+
arg1: T1
17+
): Readonly<Statics> & { new(): T1 & Instance };
18+
19+
toString(): string;
20+
}
21+
22+
declare class Mixin<T> {
23+
static create<T>(
24+
args?: T
25+
): Mixin<T>;
26+
}
27+
declare const Observable: Mixin<{}>
28+
declare class EmberObject extends CoreObject.extend(Observable) {}
29+
declare class CoreView extends EmberObject.extend({}) {}
30+
declare class Component extends CoreView.extend({}) {}
31+
32+
//// [index.js]
33+
export class MyComponent extends Component {
34+
35+
}
36+
37+
38+
39+
40+
//// [index.d.ts]
41+
export class MyComponent extends Component {
42+
}

tests/baselines/reference/narrowingByTypeofInSwitch.symbols

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,9 +404,9 @@ function exhaustiveChecksGenerics<T extends L | R | number | string>(x: T): stri
404404
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 146, 69))
405405

406406
case 'number': return x.toString(2);
407-
>x.toString : Symbol(toString, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 2 more)
407+
>x.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 2 more)
408408
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 146, 69))
409-
>toString : Symbol(toString, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 2 more)
409+
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 2 more)
410410

411411
case 'string': return x;
412412
>x : Symbol(x, Decl(narrowingByTypeofInSwitch.ts, 146, 69))
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// #37015 - test asserts lack of crash
2+
3+
// @allowJs: true
4+
// @checkJs: true
5+
// @declaration: true
6+
// @emitDeclarationOnly: true
7+
// @incremental: true
8+
// @tsBuildInfoFile: .tsbuildinfo
9+
// @noTypesAndSymbols: true
10+
11+
// @Filename: globals.d.ts
12+
13+
declare class CoreObject {
14+
static extend<
15+
Statics,
16+
Instance extends B1,
17+
T1,
18+
B1
19+
>(
20+
this: Statics & { new(): Instance },
21+
arg1: T1
22+
): Readonly<Statics> & { new(): T1 & Instance };
23+
24+
toString(): string;
25+
}
26+
27+
declare class Mixin<T> {
28+
static create<T>(
29+
args?: T
30+
): Mixin<T>;
31+
}
32+
declare const Observable: Mixin<{}>
33+
declare class EmberObject extends CoreObject.extend(Observable) {}
34+
declare class CoreView extends EmberObject.extend({}) {}
35+
declare class Component extends CoreView.extend({}) {}
36+
37+
// @Filename: index.js
38+
39+
export class MyComponent extends Component {
40+
41+
}

0 commit comments

Comments
 (0)