diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 65342c5188..2c4999e516 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7296,7 +7296,8 @@ namespace ts { } function getConstraintDeclaration(type: TypeParameter) { - return type.symbol && getDeclarationOfKind(type.symbol, SyntaxKind.TypeParameter).constraint; + const decl = type.symbol && getDeclarationOfKind(type.symbol, SyntaxKind.TypeParameter); + return decl && decl.constraint; } function getInferredTypeParameterConstraint(typeParameter: TypeParameter) { diff --git a/tests/baselines/reference/noCrashOnThisTypeUsage.js b/tests/baselines/reference/noCrashOnThisTypeUsage.js new file mode 100644 index 0000000000..32fb972c86 --- /dev/null +++ b/tests/baselines/reference/noCrashOnThisTypeUsage.js @@ -0,0 +1,48 @@ +//// [noCrashOnThisTypeUsage.ts] +interface IListenable { + changeListeners: Function[] | null + observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean): void +} + +function notifyListeners(listenable: IListenable, change: T) { +} + +export class ObservableValue { + constructor( + public value: T + ) { + const newValue: T = value; + const oldValue: any = null; + notifyListeners(this, { + type: "update", + object: this, + newValue, + oldValue + }); + } + changeListeners: Function[] | null = []; + observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean) {} +} + +//// [noCrashOnThisTypeUsage.js] +"use strict"; +exports.__esModule = true; +function notifyListeners(listenable, change) { +} +var ObservableValue = /** @class */ (function () { + function ObservableValue(value) { + this.value = value; + this.changeListeners = []; + var newValue = value; + var oldValue = null; + notifyListeners(this, { + type: "update", + object: this, + newValue: newValue, + oldValue: oldValue + }); + } + ObservableValue.prototype.observe = function (handler, fireImmediately) { }; + return ObservableValue; +}()); +exports.ObservableValue = ObservableValue; diff --git a/tests/baselines/reference/noCrashOnThisTypeUsage.symbols b/tests/baselines/reference/noCrashOnThisTypeUsage.symbols new file mode 100644 index 0000000000..84ab25a339 --- /dev/null +++ b/tests/baselines/reference/noCrashOnThisTypeUsage.symbols @@ -0,0 +1,73 @@ +=== tests/cases/compiler/noCrashOnThisTypeUsage.ts === +interface IListenable { +>IListenable : Symbol(IListenable, Decl(noCrashOnThisTypeUsage.ts, 0, 0)) + + changeListeners: Function[] | null +>changeListeners : Symbol(IListenable.changeListeners, Decl(noCrashOnThisTypeUsage.ts, 0, 23)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean): void +>observe : Symbol(IListenable.observe, Decl(noCrashOnThisTypeUsage.ts, 1, 38)) +>handler : Symbol(handler, Decl(noCrashOnThisTypeUsage.ts, 2, 12)) +>change : Symbol(change, Decl(noCrashOnThisTypeUsage.ts, 2, 22)) +>oldValue : Symbol(oldValue, Decl(noCrashOnThisTypeUsage.ts, 2, 34)) +>fireImmediately : Symbol(fireImmediately, Decl(noCrashOnThisTypeUsage.ts, 2, 59)) +} + +function notifyListeners(listenable: IListenable, change: T) { +>notifyListeners : Symbol(notifyListeners, Decl(noCrashOnThisTypeUsage.ts, 3, 1)) +>T : Symbol(T, Decl(noCrashOnThisTypeUsage.ts, 5, 25)) +>listenable : Symbol(listenable, Decl(noCrashOnThisTypeUsage.ts, 5, 28)) +>IListenable : Symbol(IListenable, Decl(noCrashOnThisTypeUsage.ts, 0, 0)) +>change : Symbol(change, Decl(noCrashOnThisTypeUsage.ts, 5, 52)) +>T : Symbol(T, Decl(noCrashOnThisTypeUsage.ts, 5, 25)) +} + +export class ObservableValue { +>ObservableValue : Symbol(ObservableValue, Decl(noCrashOnThisTypeUsage.ts, 6, 1)) +>T : Symbol(T, Decl(noCrashOnThisTypeUsage.ts, 8, 29)) + + constructor( + public value: T +>value : Symbol(ObservableValue.value, Decl(noCrashOnThisTypeUsage.ts, 9, 16)) +>T : Symbol(T, Decl(noCrashOnThisTypeUsage.ts, 8, 29)) + + ) { + const newValue: T = value; +>newValue : Symbol(newValue, Decl(noCrashOnThisTypeUsage.ts, 12, 13)) +>T : Symbol(T, Decl(noCrashOnThisTypeUsage.ts, 8, 29)) +>value : Symbol(value, Decl(noCrashOnThisTypeUsage.ts, 9, 16)) + + const oldValue: any = null; +>oldValue : Symbol(oldValue, Decl(noCrashOnThisTypeUsage.ts, 13, 13)) + + notifyListeners(this, { +>notifyListeners : Symbol(notifyListeners, Decl(noCrashOnThisTypeUsage.ts, 3, 1)) +>this : Symbol(ObservableValue, Decl(noCrashOnThisTypeUsage.ts, 6, 1)) + + type: "update", +>type : Symbol(type, Decl(noCrashOnThisTypeUsage.ts, 14, 31)) + + object: this, +>object : Symbol(object, Decl(noCrashOnThisTypeUsage.ts, 15, 27)) +>this : Symbol(ObservableValue, Decl(noCrashOnThisTypeUsage.ts, 6, 1)) + + newValue, +>newValue : Symbol(newValue, Decl(noCrashOnThisTypeUsage.ts, 16, 25)) + + oldValue +>oldValue : Symbol(oldValue, Decl(noCrashOnThisTypeUsage.ts, 17, 21)) + + }); + } + changeListeners: Function[] | null = []; +>changeListeners : Symbol(ObservableValue.changeListeners, Decl(noCrashOnThisTypeUsage.ts, 20, 5)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean) {} +>observe : Symbol(ObservableValue.observe, Decl(noCrashOnThisTypeUsage.ts, 21, 44)) +>handler : Symbol(handler, Decl(noCrashOnThisTypeUsage.ts, 22, 12)) +>change : Symbol(change, Decl(noCrashOnThisTypeUsage.ts, 22, 22)) +>oldValue : Symbol(oldValue, Decl(noCrashOnThisTypeUsage.ts, 22, 34)) +>fireImmediately : Symbol(fireImmediately, Decl(noCrashOnThisTypeUsage.ts, 22, 59)) +} diff --git a/tests/baselines/reference/noCrashOnThisTypeUsage.types b/tests/baselines/reference/noCrashOnThisTypeUsage.types new file mode 100644 index 0000000000..81851f96a5 --- /dev/null +++ b/tests/baselines/reference/noCrashOnThisTypeUsage.types @@ -0,0 +1,80 @@ +=== tests/cases/compiler/noCrashOnThisTypeUsage.ts === +interface IListenable { +>IListenable : IListenable + + changeListeners: Function[] | null +>changeListeners : Function[] | null +>Function : Function +>null : null + + observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean): void +>observe : (handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean | undefined) => void +>handler : (change: any, oldValue?: any) => void +>change : any +>oldValue : any +>fireImmediately : boolean | undefined +} + +function notifyListeners(listenable: IListenable, change: T) { +>notifyListeners : (listenable: IListenable, change: T) => void +>T : T +>listenable : IListenable +>IListenable : IListenable +>change : T +>T : T +} + +export class ObservableValue { +>ObservableValue : ObservableValue +>T : T + + constructor( + public value: T +>value : T +>T : T + + ) { + const newValue: T = value; +>newValue : T +>T : T +>value : T + + const oldValue: any = null; +>oldValue : any +>null : null + + notifyListeners(this, { +>notifyListeners(this, { type: "update", object: this, newValue, oldValue }) : void +>notifyListeners : (listenable: IListenable, change: T) => void +>this : this +>{ type: "update", object: this, newValue, oldValue } : { type: string; object: this; newValue: T; oldValue: any; } + + type: "update", +>type : string +>"update" : "update" + + object: this, +>object : this +>this : this + + newValue, +>newValue : T + + oldValue +>oldValue : any + + }); + } + changeListeners: Function[] | null = []; +>changeListeners : Function[] | null +>Function : Function +>null : null +>[] : never[] + + observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean) {} +>observe : (handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean | undefined) => void +>handler : (change: any, oldValue?: any) => void +>change : any +>oldValue : any +>fireImmediately : boolean | undefined +} diff --git a/tests/cases/compiler/noCrashOnThisTypeUsage.ts b/tests/cases/compiler/noCrashOnThisTypeUsage.ts new file mode 100644 index 0000000000..7f3832a70d --- /dev/null +++ b/tests/cases/compiler/noCrashOnThisTypeUsage.ts @@ -0,0 +1,26 @@ +// @strict: true + +interface IListenable { + changeListeners: Function[] | null + observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean): void +} + +function notifyListeners(listenable: IListenable, change: T) { +} + +export class ObservableValue { + constructor( + public value: T + ) { + const newValue: T = value; + const oldValue: any = null; + notifyListeners(this, { + type: "update", + object: this, + newValue, + oldValue + }); + } + changeListeners: Function[] | null = []; + observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean) {} +} \ No newline at end of file