There exist type parameters with symbols but without TypeParameterDeclaration nodes (#23690)

* There exist type parameters with symbols but without TypeParameterDeclaration nodes

* Add test
This commit is contained in:
Wesley Wigham 2018-04-25 15:53:06 -07:00 committed by GitHub
parent 4dc4b8d777
commit 4a6888a850
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 229 additions and 1 deletions

View file

@ -7296,7 +7296,8 @@ namespace ts {
}
function getConstraintDeclaration(type: TypeParameter) {
return type.symbol && getDeclarationOfKind<TypeParameterDeclaration>(type.symbol, SyntaxKind.TypeParameter).constraint;
const decl = type.symbol && getDeclarationOfKind<TypeParameterDeclaration>(type.symbol, SyntaxKind.TypeParameter);
return decl && decl.constraint;
}
function getInferredTypeParameterConstraint(typeParameter: TypeParameter) {

View file

@ -0,0 +1,48 @@
//// [noCrashOnThisTypeUsage.ts]
interface IListenable {
changeListeners: Function[] | null
observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean): void
}
function notifyListeners<T>(listenable: IListenable, change: T) {
}
export class ObservableValue<T> {
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;

View file

@ -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<T>(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<T> {
>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))
}

View file

@ -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<T>(listenable: IListenable, change: T) {
>notifyListeners : <T>(listenable: IListenable, change: T) => void
>T : T
>listenable : IListenable
>IListenable : IListenable
>change : T
>T : T
}
export class ObservableValue<T> {
>ObservableValue : ObservableValue<T>
>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 : <T>(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
}

View file

@ -0,0 +1,26 @@
// @strict: true
interface IListenable {
changeListeners: Function[] | null
observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean): void
}
function notifyListeners<T>(listenable: IListenable, change: T) {
}
export class ObservableValue<T> {
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) {}
}