In JS, this assignments in constructors are preferred and nullable initializers become any (#22882)

* First draft:in js, constructor declaration is preferred

* Add tests

* initializer of null|undefined gives any in JS

Also move this-assignment fixes out of binder. I'm going to put it in
the checker instead.

* In JS, initializer null|undefined: any, []: any[]

* First draft of js prefer-ctor-types overhaul

* Update tests, update baselines

* Improve readability of constructor-type preference

* Cleanup: Remove TODO and duplication

* Add noImplicitAny errors

* Add comment
This commit is contained in:
Nathan Shively-Sanders
2018-03-26 13:42:34 -07:00
committed by GitHub
parent fa794f6ee1
commit c9ac15ae56
18 changed files with 1340 additions and 121 deletions

View File

@@ -4255,10 +4255,12 @@ namespace ts {
return getWidenedLiteralType(checkExpressionCached(specialDeclaration));
}
const types: Type[] = [];
let constructorTypes: Type[];
let definedInConstructor = false;
let definedInMethod = false;
let jsDocType: Type;
for (const declaration of symbol.declarations) {
let declarationInConstructor = false;
const expression = declaration.kind === SyntaxKind.BinaryExpression ? <BinaryExpression>declaration :
declaration.kind === SyntaxKind.PropertyAccessExpression ? <BinaryExpression>getAncestor(declaration, SyntaxKind.BinaryExpression) :
undefined;
@@ -4271,9 +4273,10 @@ namespace ts {
const thisContainer = getThisContainer(expression, /*includeArrowFunctions*/ false);
// Properties defined in a constructor (or javascript constructor function) don't get undefined added.
// Function expressions that are assigned to the prototype count as methods.
if (thisContainer.kind === SyntaxKind.Constructor ||
declarationInConstructor = thisContainer.kind === SyntaxKind.Constructor ||
thisContainer.kind === SyntaxKind.FunctionDeclaration ||
(thisContainer.kind === SyntaxKind.FunctionExpression && !isPrototypePropertyAssignment(thisContainer.parent))) {
(thisContainer.kind === SyntaxKind.FunctionExpression && !isPrototypePropertyAssignment(thisContainer.parent));
if (declarationInConstructor) {
definedInConstructor = true;
}
else {
@@ -4296,14 +4299,37 @@ namespace ts {
}
else if (!jsDocType) {
// If we don't have an explicit JSDoc type, get the type from the expression.
types.push(getWidenedLiteralType(checkExpressionCached(expression.right)));
const type = getWidenedLiteralType(checkExpressionCached(expression.right));
let anyedType = type;
if (isEmptyArrayLiteralType(type)) {
anyedType = anyArrayType;
if (noImplicitAny) {
reportImplicitAnyError(expression, anyArrayType);
}
}
types.push(anyedType);
if (declarationInConstructor) {
(constructorTypes || (constructorTypes = [])).push(anyedType);
}
}
}
const type = jsDocType || getUnionType(types, UnionReduction.Subtype);
return getWidenedType(addOptionality(type, definedInMethod && !definedInConstructor));
let type = jsDocType;
if (!type) {
// use only the constructor types unless only null | undefined (including widening variants) were assigned there
const sourceTypes = some(constructorTypes, t => !!(t.flags & ~(TypeFlags.Nullable | TypeFlags.ContainsWideningType))) ? constructorTypes : types;
type = getUnionType(sourceTypes, UnionReduction.Subtype);
}
const widened = getWidenedType(addOptionality(type, definedInMethod && !definedInConstructor));
if (filterType(widened, t => !!(t.flags & ~TypeFlags.Nullable)) === neverType) {
if (noImplicitAny) {
reportImplicitAnyError(symbol.valueDeclaration, anyType);
}
return anyType;
}
return widened;
}
// Return the type implied by a binding pattern element. This is the type of the initializer of the element if
// one is present. Otherwise, if the element is itself a binding pattern, it is the type implied by the binding
// pattern. Otherwise, it is the type any.
@@ -11394,6 +11420,7 @@ namespace ts {
const typeAsString = typeToString(getWidenedType(type));
let diagnostic: DiagnosticMessage;
switch (declaration.kind) {
case SyntaxKind.BinaryExpression:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
diagnostic = Diagnostics.Member_0_implicitly_has_an_1_type;
@@ -19689,11 +19716,27 @@ namespace ts {
}
function checkDeclarationInitializer(declaration: HasExpressionInitializer) {
const initializer = isInJavaScriptFile(declaration) && getDeclaredJavascriptInitializer(declaration) || declaration.initializer;
const inJs = isInJavaScriptFile(declaration);
const initializer = inJs && getDeclaredJavascriptInitializer(declaration) || declaration.initializer;
const type = getTypeOfExpression(initializer, /*cache*/ true);
return getCombinedNodeFlags(declaration) & NodeFlags.Const ||
const widened = getCombinedNodeFlags(declaration) & NodeFlags.Const ||
(getCombinedModifierFlags(declaration) & ModifierFlags.Readonly && !isParameterPropertyDeclaration(declaration)) ||
isTypeAssertion(initializer) ? type : getWidenedLiteralType(type);
if (inJs) {
if (widened.flags & TypeFlags.Nullable) {
if (noImplicitAny) {
reportImplicitAnyError(declaration, anyType);
}
return anyType;
}
else if (isEmptyArrayLiteralType(widened)) {
if (noImplicitAny) {
reportImplicitAnyError(declaration, anyArrayType);
}
return anyArrayType;
}
}
return widened;
}
function isLiteralOfContextualType(candidateType: Type, contextualType: Type): boolean {

View File

@@ -0,0 +1,148 @@
tests/cases/conformance/salsa/a.js(14,13): error TS7008: Member 'inMethodNullable' implicitly has an 'any' type.
tests/cases/conformance/salsa/a.js(20,9): error TS2322: Type '"string"' is not assignable to type 'number'.
tests/cases/conformance/salsa/a.js(39,9): error TS2322: Type 'false' is not assignable to type 'number'.
tests/cases/conformance/salsa/a.js(93,13): error TS2334: 'this' cannot be referenced in a static property initializer.
tests/cases/conformance/salsa/a.js(96,13): error TS2334: 'this' cannot be referenced in a static property initializer.
==== tests/cases/conformance/salsa/a.js (5 errors) ====
class C {
constructor() {
if (Math.random()) {
this.inConstructor = 0;
}
else {
this.inConstructor = "string"
}
this.inMultiple = 0;
}
method() {
if (Math.random()) {
this.inMethod = 0;
this.inMethodNullable = null;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS7008: Member 'inMethodNullable' implicitly has an 'any' type.
}
else {
this.inMethod = "string"
this.inMethodNullable = undefined;
}
this.inMultiple = "string";
~~~~~~~~~~~~~~~
!!! error TS2322: Type '"string"' is not assignable to type 'number'.
this.inMultipleMethods = "string";
var action = () => {
if (Math.random()) {
this.inNestedArrowFunction = 0;
}
else {
this.inNestedArrowFunction = "string"
}
};
}
get() {
if (Math.random()) {
this.inGetter = 0;
}
else {
this.inGetter = "string"
}
this.inMultiple = false;
~~~~~~~~~~~~~~~
!!! error TS2322: Type 'false' is not assignable to type 'number'.
this.inMultipleMethods = false;
}
set() {
if (Math.random()) {
this.inSetter = 0;
}
else {
this.inSetter = "string"
}
}
prop = () => {
if (Math.random()) {
this.inPropertyDeclaration = 0;
}
else {
this.inPropertyDeclaration = "string"
}
}
static method() {
if (Math.random()) {
this.inStaticMethod = 0;
}
else {
this.inStaticMethod = "string"
}
var action = () => {
if (Math.random()) {
this.inStaticNestedArrowFunction = 0;
}
else {
this.inStaticNestedArrowFunction = "string"
}
};
}
static get() {
if (Math.random()) {
this.inStaticGetter = 0;
}
else {
this.inStaticGetter = "string"
}
}
static set() {
if (Math.random()) {
this.inStaticSetter = 0;
}
else {
this.inStaticSetter = "string"
}
}
static prop = () => {
if (Math.random()) {
this.inStaticPropertyDeclaration = 0;
~~~~
!!! error TS2334: 'this' cannot be referenced in a static property initializer.
}
else {
this.inStaticPropertyDeclaration = "string"
~~~~
!!! error TS2334: 'this' cannot be referenced in a static property initializer.
}
}
}
==== tests/cases/conformance/salsa/b.ts (0 errors) ====
var c = new C();
var stringOrNumber: string | number;
var stringOrNumber = c.inConstructor;
var stringOrNumberOrUndefined: string | number | undefined;
var stringOrNumberOrUndefined = c.inMethod;
var stringOrNumberOrUndefined = c.inGetter;
var stringOrNumberOrUndefined = c.inSetter;
var stringOrNumberOrUndefined = c.inPropertyDeclaration;
var stringOrNumberOrUndefined = c.inNestedArrowFunction
var stringOrNumberOrBoolean: string | number | boolean;
var number: number;
var number = c.inMultiple;
var stringOrBooleanOrUndefined : string | boolean | undefined;
var stringOrBooleanOrUndefined = c.inMultipleMethods;
var any: any;
var any = c.inMethodNullable;
var stringOrNumberOrUndefined = C.inStaticMethod;
var stringOrNumberOrUndefined = C.inStaticGetter;
var stringOrNumberOrUndefined = C.inStaticSetter;
var stringOrNumberOrUndefined = C.inStaticPropertyDeclaration;
var stringOrNumberOrUndefined = C.inStaticNestedArrowFunction;

View File

@@ -14,11 +14,14 @@ class C {
method() {
if (Math.random()) {
this.inMethod = 0;
this.inMethodNullable = null;
}
else {
this.inMethod = "string"
this.inMethodNullable = undefined;
}
this.inMultiple = "string";
this.inMultipleMethods = "string";
var action = () => {
if (Math.random()) {
@@ -37,6 +40,7 @@ class C {
this.inGetter = "string"
}
this.inMultiple = false;
this.inMultipleMethods = false;
}
set() {
if (Math.random()) {
@@ -113,7 +117,12 @@ var stringOrNumberOrUndefined = c.inNestedArrowFunction
var stringOrNumberOrBoolean: string | number | boolean;
var stringOrNumberOrBoolean = c.inMultiple;
var number: number;
var number = c.inMultiple;
var stringOrBooleanOrUndefined : string | boolean | undefined;
var stringOrBooleanOrUndefined = c.inMultipleMethods;
var any: any;
var any = c.inMethodNullable;
var stringOrNumberOrUndefined = C.inStaticMethod;
@@ -148,11 +157,14 @@ var C = /** @class */ (function () {
var _this = this;
if (Math.random()) {
this.inMethod = 0;
this.inMethodNullable = null;
}
else {
this.inMethod = "string";
this.inMethodNullable = undefined;
}
this.inMultiple = "string";
this.inMultipleMethods = "string";
var action = function () {
if (Math.random()) {
_this.inNestedArrowFunction = 0;
@@ -170,6 +182,7 @@ var C = /** @class */ (function () {
this.inGetter = "string";
}
this.inMultiple = false;
this.inMultipleMethods = false;
};
C.prototype.set = function () {
if (Math.random()) {
@@ -232,7 +245,12 @@ var stringOrNumberOrUndefined = c.inSetter;
var stringOrNumberOrUndefined = c.inPropertyDeclaration;
var stringOrNumberOrUndefined = c.inNestedArrowFunction;
var stringOrNumberOrBoolean;
var stringOrNumberOrBoolean = c.inMultiple;
var number;
var number = c.inMultiple;
var stringOrBooleanOrUndefined;
var stringOrBooleanOrUndefined = c.inMultipleMethods;
var any;
var any = c.inMethodNullable;
var stringOrNumberOrUndefined = C.inStaticMethod;
var stringOrNumberOrUndefined = C.inStaticGetter;
var stringOrNumberOrUndefined = C.inStaticSetter;

View File

@@ -20,9 +20,9 @@ class C {
>inConstructor : Symbol(C.inConstructor, Decl(a.js, 2, 28), Decl(a.js, 5, 14))
}
this.inMultiple = 0;
>this.inMultiple : Symbol(C.inMultiple, Decl(a.js, 7, 9), Decl(a.js, 16, 9), Decl(a.js, 34, 9))
>this.inMultiple : Symbol(C.inMultiple, Decl(a.js, 7, 9), Decl(a.js, 18, 9), Decl(a.js, 37, 9))
>this : Symbol(C, Decl(a.js, 0, 0))
>inMultiple : Symbol(C.inMultiple, Decl(a.js, 7, 9), Decl(a.js, 16, 9), Decl(a.js, 34, 9))
>inMultiple : Symbol(C.inMultiple, Decl(a.js, 7, 9), Decl(a.js, 18, 9), Decl(a.js, 37, 9))
}
method() {
>method : Symbol(C.method, Decl(a.js, 9, 5))
@@ -33,23 +33,39 @@ class C {
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
this.inMethod = 0;
>this.inMethod : Symbol(C.inMethod, Decl(a.js, 11, 28), Decl(a.js, 14, 14))
>this.inMethod : Symbol(C.inMethod, Decl(a.js, 11, 28), Decl(a.js, 15, 14))
>this : Symbol(C, Decl(a.js, 0, 0))
>inMethod : Symbol(C.inMethod, Decl(a.js, 11, 28), Decl(a.js, 14, 14))
>inMethod : Symbol(C.inMethod, Decl(a.js, 11, 28), Decl(a.js, 15, 14))
this.inMethodNullable = null;
>this.inMethodNullable : Symbol(C.inMethodNullable, Decl(a.js, 12, 30), Decl(a.js, 16, 36))
>this : Symbol(C, Decl(a.js, 0, 0))
>inMethodNullable : Symbol(C.inMethodNullable, Decl(a.js, 12, 30), Decl(a.js, 16, 36))
}
else {
this.inMethod = "string"
>this.inMethod : Symbol(C.inMethod, Decl(a.js, 11, 28), Decl(a.js, 14, 14))
>this.inMethod : Symbol(C.inMethod, Decl(a.js, 11, 28), Decl(a.js, 15, 14))
>this : Symbol(C, Decl(a.js, 0, 0))
>inMethod : Symbol(C.inMethod, Decl(a.js, 11, 28), Decl(a.js, 14, 14))
>inMethod : Symbol(C.inMethod, Decl(a.js, 11, 28), Decl(a.js, 15, 14))
this.inMethodNullable = undefined;
>this.inMethodNullable : Symbol(C.inMethodNullable, Decl(a.js, 12, 30), Decl(a.js, 16, 36))
>this : Symbol(C, Decl(a.js, 0, 0))
>inMethodNullable : Symbol(C.inMethodNullable, Decl(a.js, 12, 30), Decl(a.js, 16, 36))
>undefined : Symbol(undefined)
}
this.inMultiple = "string";
>this.inMultiple : Symbol(C.inMultiple, Decl(a.js, 7, 9), Decl(a.js, 16, 9), Decl(a.js, 34, 9))
>this.inMultiple : Symbol(C.inMultiple, Decl(a.js, 7, 9), Decl(a.js, 18, 9), Decl(a.js, 37, 9))
>this : Symbol(C, Decl(a.js, 0, 0))
>inMultiple : Symbol(C.inMultiple, Decl(a.js, 7, 9), Decl(a.js, 16, 9), Decl(a.js, 34, 9))
>inMultiple : Symbol(C.inMultiple, Decl(a.js, 7, 9), Decl(a.js, 18, 9), Decl(a.js, 37, 9))
this.inMultipleMethods = "string";
>this.inMultipleMethods : Symbol(C.inMultipleMethods, Decl(a.js, 19, 35), Decl(a.js, 38, 32))
>this : Symbol(C, Decl(a.js, 0, 0))
>inMultipleMethods : Symbol(C.inMultipleMethods, Decl(a.js, 19, 35), Decl(a.js, 38, 32))
var action = () => {
>action : Symbol(action, Decl(a.js, 19, 11))
>action : Symbol(action, Decl(a.js, 22, 11))
if (Math.random()) {
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
@@ -57,20 +73,20 @@ class C {
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
this.inNestedArrowFunction = 0;
>this.inNestedArrowFunction : Symbol(C.inNestedArrowFunction, Decl(a.js, 20, 32), Decl(a.js, 23, 18))
>this.inNestedArrowFunction : Symbol(C.inNestedArrowFunction, Decl(a.js, 23, 32), Decl(a.js, 26, 18))
>this : Symbol(C, Decl(a.js, 0, 0))
>inNestedArrowFunction : Symbol(C.inNestedArrowFunction, Decl(a.js, 20, 32), Decl(a.js, 23, 18))
>inNestedArrowFunction : Symbol(C.inNestedArrowFunction, Decl(a.js, 23, 32), Decl(a.js, 26, 18))
}
else {
this.inNestedArrowFunction = "string"
>this.inNestedArrowFunction : Symbol(C.inNestedArrowFunction, Decl(a.js, 20, 32), Decl(a.js, 23, 18))
>this.inNestedArrowFunction : Symbol(C.inNestedArrowFunction, Decl(a.js, 23, 32), Decl(a.js, 26, 18))
>this : Symbol(C, Decl(a.js, 0, 0))
>inNestedArrowFunction : Symbol(C.inNestedArrowFunction, Decl(a.js, 20, 32), Decl(a.js, 23, 18))
>inNestedArrowFunction : Symbol(C.inNestedArrowFunction, Decl(a.js, 23, 32), Decl(a.js, 26, 18))
}
};
}
get() {
>get : Symbol(C.get, Decl(a.js, 27, 5))
>get : Symbol(C.get, Decl(a.js, 30, 5))
if (Math.random()) {
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
@@ -78,23 +94,28 @@ class C {
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
this.inGetter = 0;
>this.inGetter : Symbol(C.inGetter, Decl(a.js, 29, 28), Decl(a.js, 32, 14))
>this.inGetter : Symbol(C.inGetter, Decl(a.js, 32, 28), Decl(a.js, 35, 14))
>this : Symbol(C, Decl(a.js, 0, 0))
>inGetter : Symbol(C.inGetter, Decl(a.js, 29, 28), Decl(a.js, 32, 14))
>inGetter : Symbol(C.inGetter, Decl(a.js, 32, 28), Decl(a.js, 35, 14))
}
else {
this.inGetter = "string"
>this.inGetter : Symbol(C.inGetter, Decl(a.js, 29, 28), Decl(a.js, 32, 14))
>this.inGetter : Symbol(C.inGetter, Decl(a.js, 32, 28), Decl(a.js, 35, 14))
>this : Symbol(C, Decl(a.js, 0, 0))
>inGetter : Symbol(C.inGetter, Decl(a.js, 29, 28), Decl(a.js, 32, 14))
>inGetter : Symbol(C.inGetter, Decl(a.js, 32, 28), Decl(a.js, 35, 14))
}
this.inMultiple = false;
>this.inMultiple : Symbol(C.inMultiple, Decl(a.js, 7, 9), Decl(a.js, 16, 9), Decl(a.js, 34, 9))
>this.inMultiple : Symbol(C.inMultiple, Decl(a.js, 7, 9), Decl(a.js, 18, 9), Decl(a.js, 37, 9))
>this : Symbol(C, Decl(a.js, 0, 0))
>inMultiple : Symbol(C.inMultiple, Decl(a.js, 7, 9), Decl(a.js, 16, 9), Decl(a.js, 34, 9))
>inMultiple : Symbol(C.inMultiple, Decl(a.js, 7, 9), Decl(a.js, 18, 9), Decl(a.js, 37, 9))
this.inMultipleMethods = false;
>this.inMultipleMethods : Symbol(C.inMultipleMethods, Decl(a.js, 19, 35), Decl(a.js, 38, 32))
>this : Symbol(C, Decl(a.js, 0, 0))
>inMultipleMethods : Symbol(C.inMultipleMethods, Decl(a.js, 19, 35), Decl(a.js, 38, 32))
}
set() {
>set : Symbol(C.set, Decl(a.js, 36, 5))
>set : Symbol(C.set, Decl(a.js, 40, 5))
if (Math.random()) {
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
@@ -102,19 +123,19 @@ class C {
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
this.inSetter = 0;
>this.inSetter : Symbol(C.inSetter, Decl(a.js, 38, 28), Decl(a.js, 41, 14))
>this.inSetter : Symbol(C.inSetter, Decl(a.js, 42, 28), Decl(a.js, 45, 14))
>this : Symbol(C, Decl(a.js, 0, 0))
>inSetter : Symbol(C.inSetter, Decl(a.js, 38, 28), Decl(a.js, 41, 14))
>inSetter : Symbol(C.inSetter, Decl(a.js, 42, 28), Decl(a.js, 45, 14))
}
else {
this.inSetter = "string"
>this.inSetter : Symbol(C.inSetter, Decl(a.js, 38, 28), Decl(a.js, 41, 14))
>this.inSetter : Symbol(C.inSetter, Decl(a.js, 42, 28), Decl(a.js, 45, 14))
>this : Symbol(C, Decl(a.js, 0, 0))
>inSetter : Symbol(C.inSetter, Decl(a.js, 38, 28), Decl(a.js, 41, 14))
>inSetter : Symbol(C.inSetter, Decl(a.js, 42, 28), Decl(a.js, 45, 14))
}
}
prop = () => {
>prop : Symbol(C.prop, Decl(a.js, 44, 5))
>prop : Symbol(C.prop, Decl(a.js, 48, 5))
if (Math.random()) {
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
@@ -122,19 +143,19 @@ class C {
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
this.inPropertyDeclaration = 0;
>this.inPropertyDeclaration : Symbol(C.inPropertyDeclaration, Decl(a.js, 46, 28), Decl(a.js, 49, 14))
>this.inPropertyDeclaration : Symbol(C.inPropertyDeclaration, Decl(a.js, 50, 28), Decl(a.js, 53, 14))
>this : Symbol(C, Decl(a.js, 0, 0))
>inPropertyDeclaration : Symbol(C.inPropertyDeclaration, Decl(a.js, 46, 28), Decl(a.js, 49, 14))
>inPropertyDeclaration : Symbol(C.inPropertyDeclaration, Decl(a.js, 50, 28), Decl(a.js, 53, 14))
}
else {
this.inPropertyDeclaration = "string"
>this.inPropertyDeclaration : Symbol(C.inPropertyDeclaration, Decl(a.js, 46, 28), Decl(a.js, 49, 14))
>this.inPropertyDeclaration : Symbol(C.inPropertyDeclaration, Decl(a.js, 50, 28), Decl(a.js, 53, 14))
>this : Symbol(C, Decl(a.js, 0, 0))
>inPropertyDeclaration : Symbol(C.inPropertyDeclaration, Decl(a.js, 46, 28), Decl(a.js, 49, 14))
>inPropertyDeclaration : Symbol(C.inPropertyDeclaration, Decl(a.js, 50, 28), Decl(a.js, 53, 14))
}
}
static method() {
>method : Symbol(C.method, Decl(a.js, 52, 5))
>method : Symbol(C.method, Decl(a.js, 56, 5))
if (Math.random()) {
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
@@ -142,19 +163,19 @@ class C {
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
this.inStaticMethod = 0;
>this.inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 54, 28), Decl(a.js, 57, 14))
>this.inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 58, 28), Decl(a.js, 61, 14))
>this : Symbol(C, Decl(a.js, 0, 0))
>inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 54, 28), Decl(a.js, 57, 14))
>inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 58, 28), Decl(a.js, 61, 14))
}
else {
this.inStaticMethod = "string"
>this.inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 54, 28), Decl(a.js, 57, 14))
>this.inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 58, 28), Decl(a.js, 61, 14))
>this : Symbol(C, Decl(a.js, 0, 0))
>inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 54, 28), Decl(a.js, 57, 14))
>inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 58, 28), Decl(a.js, 61, 14))
}
var action = () => {
>action : Symbol(action, Decl(a.js, 61, 11))
>action : Symbol(action, Decl(a.js, 65, 11))
if (Math.random()) {
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
@@ -162,20 +183,20 @@ class C {
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
this.inStaticNestedArrowFunction = 0;
>this.inStaticNestedArrowFunction : Symbol(C.inStaticNestedArrowFunction, Decl(a.js, 62, 32), Decl(a.js, 65, 18))
>this.inStaticNestedArrowFunction : Symbol(C.inStaticNestedArrowFunction, Decl(a.js, 66, 32), Decl(a.js, 69, 18))
>this : Symbol(C, Decl(a.js, 0, 0))
>inStaticNestedArrowFunction : Symbol(C.inStaticNestedArrowFunction, Decl(a.js, 62, 32), Decl(a.js, 65, 18))
>inStaticNestedArrowFunction : Symbol(C.inStaticNestedArrowFunction, Decl(a.js, 66, 32), Decl(a.js, 69, 18))
}
else {
this.inStaticNestedArrowFunction = "string"
>this.inStaticNestedArrowFunction : Symbol(C.inStaticNestedArrowFunction, Decl(a.js, 62, 32), Decl(a.js, 65, 18))
>this.inStaticNestedArrowFunction : Symbol(C.inStaticNestedArrowFunction, Decl(a.js, 66, 32), Decl(a.js, 69, 18))
>this : Symbol(C, Decl(a.js, 0, 0))
>inStaticNestedArrowFunction : Symbol(C.inStaticNestedArrowFunction, Decl(a.js, 62, 32), Decl(a.js, 65, 18))
>inStaticNestedArrowFunction : Symbol(C.inStaticNestedArrowFunction, Decl(a.js, 66, 32), Decl(a.js, 69, 18))
}
};
}
static get() {
>get : Symbol(C.get, Decl(a.js, 69, 5))
>get : Symbol(C.get, Decl(a.js, 73, 5))
if (Math.random()) {
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
@@ -183,19 +204,19 @@ class C {
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
this.inStaticGetter = 0;
>this.inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 71, 28), Decl(a.js, 74, 14))
>this.inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 75, 28), Decl(a.js, 78, 14))
>this : Symbol(C, Decl(a.js, 0, 0))
>inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 71, 28), Decl(a.js, 74, 14))
>inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 75, 28), Decl(a.js, 78, 14))
}
else {
this.inStaticGetter = "string"
>this.inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 71, 28), Decl(a.js, 74, 14))
>this.inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 75, 28), Decl(a.js, 78, 14))
>this : Symbol(C, Decl(a.js, 0, 0))
>inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 71, 28), Decl(a.js, 74, 14))
>inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 75, 28), Decl(a.js, 78, 14))
}
}
static set() {
>set : Symbol(C.set, Decl(a.js, 77, 5))
>set : Symbol(C.set, Decl(a.js, 81, 5))
if (Math.random()) {
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
@@ -203,19 +224,19 @@ class C {
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
this.inStaticSetter = 0;
>this.inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 79, 28), Decl(a.js, 82, 14))
>this.inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 83, 28), Decl(a.js, 86, 14))
>this : Symbol(C, Decl(a.js, 0, 0))
>inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 79, 28), Decl(a.js, 82, 14))
>inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 83, 28), Decl(a.js, 86, 14))
}
else {
this.inStaticSetter = "string"
>this.inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 79, 28), Decl(a.js, 82, 14))
>this.inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 83, 28), Decl(a.js, 86, 14))
>this : Symbol(C, Decl(a.js, 0, 0))
>inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 79, 28), Decl(a.js, 82, 14))
>inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 83, 28), Decl(a.js, 86, 14))
}
}
static prop = () => {
>prop : Symbol(C.prop, Decl(a.js, 85, 5))
>prop : Symbol(C.prop, Decl(a.js, 89, 5))
if (Math.random()) {
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
@@ -223,15 +244,15 @@ class C {
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
this.inStaticPropertyDeclaration = 0;
>this.inStaticPropertyDeclaration : Symbol(C.inStaticPropertyDeclaration, Decl(a.js, 87, 28), Decl(a.js, 90, 14))
>this.inStaticPropertyDeclaration : Symbol(C.inStaticPropertyDeclaration, Decl(a.js, 91, 28), Decl(a.js, 94, 14))
>this : Symbol(C, Decl(a.js, 0, 0))
>inStaticPropertyDeclaration : Symbol(C.inStaticPropertyDeclaration, Decl(a.js, 87, 28), Decl(a.js, 90, 14))
>inStaticPropertyDeclaration : Symbol(C.inStaticPropertyDeclaration, Decl(a.js, 91, 28), Decl(a.js, 94, 14))
}
else {
this.inStaticPropertyDeclaration = "string"
>this.inStaticPropertyDeclaration : Symbol(C.inStaticPropertyDeclaration, Decl(a.js, 87, 28), Decl(a.js, 90, 14))
>this.inStaticPropertyDeclaration : Symbol(C.inStaticPropertyDeclaration, Decl(a.js, 91, 28), Decl(a.js, 94, 14))
>this : Symbol(C, Decl(a.js, 0, 0))
>inStaticPropertyDeclaration : Symbol(C.inStaticPropertyDeclaration, Decl(a.js, 87, 28), Decl(a.js, 90, 14))
>inStaticPropertyDeclaration : Symbol(C.inStaticPropertyDeclaration, Decl(a.js, 91, 28), Decl(a.js, 94, 14))
}
}
}
@@ -255,71 +276,92 @@ var stringOrNumberOrUndefined: string | number | undefined;
var stringOrNumberOrUndefined = c.inMethod;
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 10, 3) ... and 6 more)
>c.inMethod : Symbol(C.inMethod, Decl(a.js, 11, 28), Decl(a.js, 14, 14))
>c.inMethod : Symbol(C.inMethod, Decl(a.js, 11, 28), Decl(a.js, 15, 14))
>c : Symbol(c, Decl(b.ts, 0, 3))
>inMethod : Symbol(C.inMethod, Decl(a.js, 11, 28), Decl(a.js, 14, 14))
>inMethod : Symbol(C.inMethod, Decl(a.js, 11, 28), Decl(a.js, 15, 14))
var stringOrNumberOrUndefined = c.inGetter;
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 10, 3) ... and 6 more)
>c.inGetter : Symbol(C.inGetter, Decl(a.js, 29, 28), Decl(a.js, 32, 14))
>c.inGetter : Symbol(C.inGetter, Decl(a.js, 32, 28), Decl(a.js, 35, 14))
>c : Symbol(c, Decl(b.ts, 0, 3))
>inGetter : Symbol(C.inGetter, Decl(a.js, 29, 28), Decl(a.js, 32, 14))
>inGetter : Symbol(C.inGetter, Decl(a.js, 32, 28), Decl(a.js, 35, 14))
var stringOrNumberOrUndefined = c.inSetter;
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 10, 3) ... and 6 more)
>c.inSetter : Symbol(C.inSetter, Decl(a.js, 38, 28), Decl(a.js, 41, 14))
>c.inSetter : Symbol(C.inSetter, Decl(a.js, 42, 28), Decl(a.js, 45, 14))
>c : Symbol(c, Decl(b.ts, 0, 3))
>inSetter : Symbol(C.inSetter, Decl(a.js, 38, 28), Decl(a.js, 41, 14))
>inSetter : Symbol(C.inSetter, Decl(a.js, 42, 28), Decl(a.js, 45, 14))
var stringOrNumberOrUndefined = c.inPropertyDeclaration;
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 10, 3) ... and 6 more)
>c.inPropertyDeclaration : Symbol(C.inPropertyDeclaration, Decl(a.js, 46, 28), Decl(a.js, 49, 14))
>c.inPropertyDeclaration : Symbol(C.inPropertyDeclaration, Decl(a.js, 50, 28), Decl(a.js, 53, 14))
>c : Symbol(c, Decl(b.ts, 0, 3))
>inPropertyDeclaration : Symbol(C.inPropertyDeclaration, Decl(a.js, 46, 28), Decl(a.js, 49, 14))
>inPropertyDeclaration : Symbol(C.inPropertyDeclaration, Decl(a.js, 50, 28), Decl(a.js, 53, 14))
var stringOrNumberOrUndefined = c.inNestedArrowFunction
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 10, 3) ... and 6 more)
>c.inNestedArrowFunction : Symbol(C.inNestedArrowFunction, Decl(a.js, 20, 32), Decl(a.js, 23, 18))
>c.inNestedArrowFunction : Symbol(C.inNestedArrowFunction, Decl(a.js, 23, 32), Decl(a.js, 26, 18))
>c : Symbol(c, Decl(b.ts, 0, 3))
>inNestedArrowFunction : Symbol(C.inNestedArrowFunction, Decl(a.js, 20, 32), Decl(a.js, 23, 18))
>inNestedArrowFunction : Symbol(C.inNestedArrowFunction, Decl(a.js, 23, 32), Decl(a.js, 26, 18))
var stringOrNumberOrBoolean: string | number | boolean;
>stringOrNumberOrBoolean : Symbol(stringOrNumberOrBoolean, Decl(b.ts, 13, 3), Decl(b.ts, 15, 3))
>stringOrNumberOrBoolean : Symbol(stringOrNumberOrBoolean, Decl(b.ts, 13, 3))
var stringOrNumberOrBoolean = c.inMultiple;
>stringOrNumberOrBoolean : Symbol(stringOrNumberOrBoolean, Decl(b.ts, 13, 3), Decl(b.ts, 15, 3))
>c.inMultiple : Symbol(C.inMultiple, Decl(a.js, 7, 9), Decl(a.js, 16, 9), Decl(a.js, 34, 9))
var number: number;
>number : Symbol(number, Decl(b.ts, 15, 3), Decl(b.ts, 16, 3))
var number = c.inMultiple;
>number : Symbol(number, Decl(b.ts, 15, 3), Decl(b.ts, 16, 3))
>c.inMultiple : Symbol(C.inMultiple, Decl(a.js, 7, 9), Decl(a.js, 18, 9), Decl(a.js, 37, 9))
>c : Symbol(c, Decl(b.ts, 0, 3))
>inMultiple : Symbol(C.inMultiple, Decl(a.js, 7, 9), Decl(a.js, 16, 9), Decl(a.js, 34, 9))
>inMultiple : Symbol(C.inMultiple, Decl(a.js, 7, 9), Decl(a.js, 18, 9), Decl(a.js, 37, 9))
var stringOrBooleanOrUndefined : string | boolean | undefined;
>stringOrBooleanOrUndefined : Symbol(stringOrBooleanOrUndefined, Decl(b.ts, 17, 3), Decl(b.ts, 18, 3))
var stringOrBooleanOrUndefined = c.inMultipleMethods;
>stringOrBooleanOrUndefined : Symbol(stringOrBooleanOrUndefined, Decl(b.ts, 17, 3), Decl(b.ts, 18, 3))
>c.inMultipleMethods : Symbol(C.inMultipleMethods, Decl(a.js, 19, 35), Decl(a.js, 38, 32))
>c : Symbol(c, Decl(b.ts, 0, 3))
>inMultipleMethods : Symbol(C.inMultipleMethods, Decl(a.js, 19, 35), Decl(a.js, 38, 32))
var any: any;
>any : Symbol(any, Decl(b.ts, 19, 3), Decl(b.ts, 20, 3))
var any = c.inMethodNullable;
>any : Symbol(any, Decl(b.ts, 19, 3), Decl(b.ts, 20, 3))
>c.inMethodNullable : Symbol(C.inMethodNullable, Decl(a.js, 12, 30), Decl(a.js, 16, 36))
>c : Symbol(c, Decl(b.ts, 0, 3))
>inMethodNullable : Symbol(C.inMethodNullable, Decl(a.js, 12, 30), Decl(a.js, 16, 36))
var stringOrNumberOrUndefined = C.inStaticMethod;
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 10, 3) ... and 6 more)
>C.inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 54, 28), Decl(a.js, 57, 14))
>C.inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 58, 28), Decl(a.js, 61, 14))
>C : Symbol(C, Decl(a.js, 0, 0))
>inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 54, 28), Decl(a.js, 57, 14))
>inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 58, 28), Decl(a.js, 61, 14))
var stringOrNumberOrUndefined = C.inStaticGetter;
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 10, 3) ... and 6 more)
>C.inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 71, 28), Decl(a.js, 74, 14))
>C.inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 75, 28), Decl(a.js, 78, 14))
>C : Symbol(C, Decl(a.js, 0, 0))
>inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 71, 28), Decl(a.js, 74, 14))
>inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 75, 28), Decl(a.js, 78, 14))
var stringOrNumberOrUndefined = C.inStaticSetter;
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 10, 3) ... and 6 more)
>C.inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 79, 28), Decl(a.js, 82, 14))
>C.inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 83, 28), Decl(a.js, 86, 14))
>C : Symbol(C, Decl(a.js, 0, 0))
>inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 79, 28), Decl(a.js, 82, 14))
>inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 83, 28), Decl(a.js, 86, 14))
var stringOrNumberOrUndefined = C.inStaticPropertyDeclaration;
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 10, 3) ... and 6 more)
>C.inStaticPropertyDeclaration : Symbol(C.inStaticPropertyDeclaration, Decl(a.js, 87, 28), Decl(a.js, 90, 14))
>C.inStaticPropertyDeclaration : Symbol(C.inStaticPropertyDeclaration, Decl(a.js, 91, 28), Decl(a.js, 94, 14))
>C : Symbol(C, Decl(a.js, 0, 0))
>inStaticPropertyDeclaration : Symbol(C.inStaticPropertyDeclaration, Decl(a.js, 87, 28), Decl(a.js, 90, 14))
>inStaticPropertyDeclaration : Symbol(C.inStaticPropertyDeclaration, Decl(a.js, 91, 28), Decl(a.js, 94, 14))
var stringOrNumberOrUndefined = C.inStaticNestedArrowFunction;
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 10, 3) ... and 6 more)
>C.inStaticNestedArrowFunction : Symbol(C.inStaticNestedArrowFunction, Decl(a.js, 62, 32), Decl(a.js, 65, 18))
>C.inStaticNestedArrowFunction : Symbol(C.inStaticNestedArrowFunction, Decl(a.js, 66, 32), Decl(a.js, 69, 18))
>C : Symbol(C, Decl(a.js, 0, 0))
>inStaticNestedArrowFunction : Symbol(C.inStaticNestedArrowFunction, Decl(a.js, 62, 32), Decl(a.js, 65, 18))
>inStaticNestedArrowFunction : Symbol(C.inStaticNestedArrowFunction, Decl(a.js, 66, 32), Decl(a.js, 69, 18))

View File

@@ -26,9 +26,9 @@ class C {
}
this.inMultiple = 0;
>this.inMultiple = 0 : 0
>this.inMultiple : string | number | boolean
>this.inMultiple : number
>this : this
>inMultiple : string | number | boolean
>inMultiple : number
>0 : 0
}
method() {
@@ -46,6 +46,13 @@ class C {
>this : this
>inMethod : string | number | undefined
>0 : 0
this.inMethodNullable = null;
>this.inMethodNullable = null : null
>this.inMethodNullable : any
>this : this
>inMethodNullable : any
>null : null
}
else {
this.inMethod = "string"
@@ -54,12 +61,26 @@ class C {
>this : this
>inMethod : string | number | undefined
>"string" : "string"
this.inMethodNullable = undefined;
>this.inMethodNullable = undefined : undefined
>this.inMethodNullable : any
>this : this
>inMethodNullable : any
>undefined : undefined
}
this.inMultiple = "string";
>this.inMultiple = "string" : "string"
>this.inMultiple : string | number | boolean
>this.inMultiple : number
>this : this
>inMultiple : string | number | boolean
>inMultiple : number
>"string" : "string"
this.inMultipleMethods = "string";
>this.inMultipleMethods = "string" : "string"
>this.inMultipleMethods : string | boolean | undefined
>this : this
>inMultipleMethods : string | boolean | undefined
>"string" : "string"
var action = () => {
@@ -115,9 +136,16 @@ class C {
}
this.inMultiple = false;
>this.inMultiple = false : false
>this.inMultiple : string | number | boolean
>this.inMultiple : number
>this : this
>inMultiple : string | number | boolean
>inMultiple : number
>false : false
this.inMultipleMethods = false;
>this.inMultipleMethods = false : false
>this.inMultipleMethods : string | boolean | undefined
>this : this
>inMultipleMethods : string | boolean | undefined
>false : false
}
set() {
@@ -352,11 +380,32 @@ var stringOrNumberOrUndefined = c.inNestedArrowFunction
var stringOrNumberOrBoolean: string | number | boolean;
>stringOrNumberOrBoolean : string | number | boolean
var stringOrNumberOrBoolean = c.inMultiple;
>stringOrNumberOrBoolean : string | number | boolean
>c.inMultiple : string | number | boolean
var number: number;
>number : number
var number = c.inMultiple;
>number : number
>c.inMultiple : number
>c : C
>inMultiple : string | number | boolean
>inMultiple : number
var stringOrBooleanOrUndefined : string | boolean | undefined;
>stringOrBooleanOrUndefined : string | boolean | undefined
var stringOrBooleanOrUndefined = c.inMultipleMethods;
>stringOrBooleanOrUndefined : string | boolean | undefined
>c.inMultipleMethods : string | boolean | undefined
>c : C
>inMultipleMethods : string | boolean | undefined
var any: any;
>any : any
var any = c.inMethodNullable;
>any : any
>c.inMethodNullable : any
>c : C
>inMethodNullable : any
var stringOrNumberOrUndefined = C.inStaticMethod;

View File

@@ -0,0 +1,52 @@
tests/cases/conformance/salsa/a.js(10,5): error TS7008: Member 'twices' implicitly has an 'any[]' type.
tests/cases/conformance/salsa/a.js(14,5): error TS2322: Type '"hi"' is not assignable to type 'number'.
tests/cases/conformance/salsa/a.js(21,5): error TS2322: Type 'false' is not assignable to type 'number'.
tests/cases/conformance/salsa/a.js(24,5): error TS2322: Type 'null' is not assignable to type 'string | undefined'.
tests/cases/conformance/salsa/a.js(25,5): error TS2322: Type 'false' is not assignable to type 'string | undefined'.
tests/cases/conformance/salsa/a.js(26,5): error TS2531: Object is possibly 'null'.
==== tests/cases/conformance/salsa/a.js (6 errors) ====
function Installer () {
// arg: number
this.arg = 0
// unknown: string | boolean | null
this.unknown = null
// twice: string | undefined
this.twice = undefined
this.twice = 'hi'
// twices: any[] | null
this.twices = []
~~~~~~~~~~~~~~~~
!!! error TS7008: Member 'twices' implicitly has an 'any[]' type.
this.twices = null
}
Installer.prototype.first = function () {
this.arg = 'hi' // error
~~~~~~~~
!!! error TS2322: Type '"hi"' is not assignable to type 'number'.
this.unknown = 'hi' // ok
this.newProperty = 1 // ok: number | boolean
this.twice = undefined // ok
this.twice = 'hi' // ok
}
Installer.prototype.second = function () {
this.arg = false // error
~~~~~~~~
!!! error TS2322: Type 'false' is not assignable to type 'number'.
this.unknown = false // ok
this.newProperty = false // ok
this.twice = null // error
~~~~~~~~~~
!!! error TS2322: Type 'null' is not assignable to type 'string | undefined'.
this.twice = false // error
~~~~~~~~~~
!!! error TS2322: Type 'false' is not assignable to type 'string | undefined'.
this.twices.push(1) // error: Object is possibly null
~~~~~~~~~~~
!!! error TS2531: Object is possibly 'null'.
if (this.twices != null) {
this.twices.push('hi')
}
}

View File

@@ -0,0 +1,111 @@
=== tests/cases/conformance/salsa/a.js ===
function Installer () {
>Installer : Symbol(Installer, Decl(a.js, 0, 0))
// arg: number
this.arg = 0
>arg : Symbol(Installer.arg, Decl(a.js, 0, 23), Decl(a.js, 12, 41), Decl(a.js, 19, 42))
// unknown: string | boolean | null
this.unknown = null
>unknown : Symbol(Installer.unknown, Decl(a.js, 2, 16), Decl(a.js, 13, 19), Decl(a.js, 20, 20))
// twice: string | undefined
this.twice = undefined
>twice : Symbol(Installer.twice, Decl(a.js, 4, 23), Decl(a.js, 6, 26), Decl(a.js, 15, 24), Decl(a.js, 16, 26), Decl(a.js, 22, 28) ... and 1 more)
>undefined : Symbol(undefined)
this.twice = 'hi'
>twice : Symbol(Installer.twice, Decl(a.js, 4, 23), Decl(a.js, 6, 26), Decl(a.js, 15, 24), Decl(a.js, 16, 26), Decl(a.js, 22, 28) ... and 1 more)
// twices: any[] | null
this.twices = []
>twices : Symbol(Installer.twices, Decl(a.js, 7, 21), Decl(a.js, 9, 20))
this.twices = null
>twices : Symbol(Installer.twices, Decl(a.js, 7, 21), Decl(a.js, 9, 20))
}
Installer.prototype.first = function () {
>Installer.prototype : Symbol(Installer.first, Decl(a.js, 11, 1))
>Installer : Symbol(Installer, Decl(a.js, 0, 0))
>prototype : Symbol(Function.prototype, Decl(lib.d.ts, --, --))
>first : Symbol(Installer.first, Decl(a.js, 11, 1))
this.arg = 'hi' // error
>this.arg : Symbol(Installer.arg, Decl(a.js, 0, 23), Decl(a.js, 12, 41), Decl(a.js, 19, 42))
>this : Symbol(Installer, Decl(a.js, 0, 0))
>arg : Symbol(Installer.arg, Decl(a.js, 0, 23), Decl(a.js, 12, 41), Decl(a.js, 19, 42))
this.unknown = 'hi' // ok
>this.unknown : Symbol(Installer.unknown, Decl(a.js, 2, 16), Decl(a.js, 13, 19), Decl(a.js, 20, 20))
>this : Symbol(Installer, Decl(a.js, 0, 0))
>unknown : Symbol(Installer.unknown, Decl(a.js, 2, 16), Decl(a.js, 13, 19), Decl(a.js, 20, 20))
this.newProperty = 1 // ok: number | boolean
>this.newProperty : Symbol(Installer.newProperty, Decl(a.js, 14, 23), Decl(a.js, 21, 24))
>this : Symbol(Installer, Decl(a.js, 0, 0))
>newProperty : Symbol(Installer.newProperty, Decl(a.js, 14, 23), Decl(a.js, 21, 24))
this.twice = undefined // ok
>this.twice : Symbol(Installer.twice, Decl(a.js, 4, 23), Decl(a.js, 6, 26), Decl(a.js, 15, 24), Decl(a.js, 16, 26), Decl(a.js, 22, 28) ... and 1 more)
>this : Symbol(Installer, Decl(a.js, 0, 0))
>twice : Symbol(Installer.twice, Decl(a.js, 4, 23), Decl(a.js, 6, 26), Decl(a.js, 15, 24), Decl(a.js, 16, 26), Decl(a.js, 22, 28) ... and 1 more)
>undefined : Symbol(undefined)
this.twice = 'hi' // ok
>this.twice : Symbol(Installer.twice, Decl(a.js, 4, 23), Decl(a.js, 6, 26), Decl(a.js, 15, 24), Decl(a.js, 16, 26), Decl(a.js, 22, 28) ... and 1 more)
>this : Symbol(Installer, Decl(a.js, 0, 0))
>twice : Symbol(Installer.twice, Decl(a.js, 4, 23), Decl(a.js, 6, 26), Decl(a.js, 15, 24), Decl(a.js, 16, 26), Decl(a.js, 22, 28) ... and 1 more)
}
Installer.prototype.second = function () {
>Installer.prototype : Symbol(Installer.second, Decl(a.js, 18, 1))
>Installer : Symbol(Installer, Decl(a.js, 0, 0))
>prototype : Symbol(Function.prototype, Decl(lib.d.ts, --, --))
>second : Symbol(Installer.second, Decl(a.js, 18, 1))
this.arg = false // error
>this.arg : Symbol(Installer.arg, Decl(a.js, 0, 23), Decl(a.js, 12, 41), Decl(a.js, 19, 42))
>this : Symbol(Installer, Decl(a.js, 0, 0))
>arg : Symbol(Installer.arg, Decl(a.js, 0, 23), Decl(a.js, 12, 41), Decl(a.js, 19, 42))
this.unknown = false // ok
>this.unknown : Symbol(Installer.unknown, Decl(a.js, 2, 16), Decl(a.js, 13, 19), Decl(a.js, 20, 20))
>this : Symbol(Installer, Decl(a.js, 0, 0))
>unknown : Symbol(Installer.unknown, Decl(a.js, 2, 16), Decl(a.js, 13, 19), Decl(a.js, 20, 20))
this.newProperty = false // ok
>this.newProperty : Symbol(Installer.newProperty, Decl(a.js, 14, 23), Decl(a.js, 21, 24))
>this : Symbol(Installer, Decl(a.js, 0, 0))
>newProperty : Symbol(Installer.newProperty, Decl(a.js, 14, 23), Decl(a.js, 21, 24))
this.twice = null // error
>this.twice : Symbol(Installer.twice, Decl(a.js, 4, 23), Decl(a.js, 6, 26), Decl(a.js, 15, 24), Decl(a.js, 16, 26), Decl(a.js, 22, 28) ... and 1 more)
>this : Symbol(Installer, Decl(a.js, 0, 0))
>twice : Symbol(Installer.twice, Decl(a.js, 4, 23), Decl(a.js, 6, 26), Decl(a.js, 15, 24), Decl(a.js, 16, 26), Decl(a.js, 22, 28) ... and 1 more)
this.twice = false // error
>this.twice : Symbol(Installer.twice, Decl(a.js, 4, 23), Decl(a.js, 6, 26), Decl(a.js, 15, 24), Decl(a.js, 16, 26), Decl(a.js, 22, 28) ... and 1 more)
>this : Symbol(Installer, Decl(a.js, 0, 0))
>twice : Symbol(Installer.twice, Decl(a.js, 4, 23), Decl(a.js, 6, 26), Decl(a.js, 15, 24), Decl(a.js, 16, 26), Decl(a.js, 22, 28) ... and 1 more)
this.twices.push(1) // error: Object is possibly null
>this.twices.push : Symbol(Array.push, Decl(lib.d.ts, --, --))
>this.twices : Symbol(Installer.twices, Decl(a.js, 7, 21), Decl(a.js, 9, 20))
>this : Symbol(Installer, Decl(a.js, 0, 0))
>twices : Symbol(Installer.twices, Decl(a.js, 7, 21), Decl(a.js, 9, 20))
>push : Symbol(Array.push, Decl(lib.d.ts, --, --))
if (this.twices != null) {
>this.twices : Symbol(Installer.twices, Decl(a.js, 7, 21), Decl(a.js, 9, 20))
>this : Symbol(Installer, Decl(a.js, 0, 0))
>twices : Symbol(Installer.twices, Decl(a.js, 7, 21), Decl(a.js, 9, 20))
this.twices.push('hi')
>this.twices.push : Symbol(Array.push, Decl(lib.d.ts, --, --))
>this.twices : Symbol(Installer.twices, Decl(a.js, 7, 21), Decl(a.js, 9, 20))
>this : Symbol(Installer, Decl(a.js, 0, 0))
>twices : Symbol(Installer.twices, Decl(a.js, 7, 21), Decl(a.js, 9, 20))
>push : Symbol(Array.push, Decl(lib.d.ts, --, --))
}
}

View File

@@ -0,0 +1,165 @@
=== tests/cases/conformance/salsa/a.js ===
function Installer () {
>Installer : () => void
// arg: number
this.arg = 0
>this.arg = 0 : 0
>this.arg : any
>this : any
>arg : any
>0 : 0
// unknown: string | boolean | null
this.unknown = null
>this.unknown = null : null
>this.unknown : any
>this : any
>unknown : any
>null : null
// twice: string | undefined
this.twice = undefined
>this.twice = undefined : undefined
>this.twice : any
>this : any
>twice : any
>undefined : undefined
this.twice = 'hi'
>this.twice = 'hi' : "hi"
>this.twice : any
>this : any
>twice : any
>'hi' : "hi"
// twices: any[] | null
this.twices = []
>this.twices = [] : never[]
>this.twices : any
>this : any
>twices : any
>[] : never[]
this.twices = null
>this.twices = null : null
>this.twices : any
>this : any
>twices : any
>null : null
}
Installer.prototype.first = function () {
>Installer.prototype.first = function () { this.arg = 'hi' // error this.unknown = 'hi' // ok this.newProperty = 1 // ok: number | boolean this.twice = undefined // ok this.twice = 'hi' // ok} : () => void
>Installer.prototype.first : any
>Installer.prototype : any
>Installer : () => void
>prototype : any
>first : any
>function () { this.arg = 'hi' // error this.unknown = 'hi' // ok this.newProperty = 1 // ok: number | boolean this.twice = undefined // ok this.twice = 'hi' // ok} : () => void
this.arg = 'hi' // error
>this.arg = 'hi' : "hi"
>this.arg : number
>this : { arg: number; unknown: string | boolean | null; twice: string | undefined; twices: any[] | null; first: () => void; newProperty: number | boolean | undefined; second: () => void; }
>arg : number
>'hi' : "hi"
this.unknown = 'hi' // ok
>this.unknown = 'hi' : "hi"
>this.unknown : string | boolean | null
>this : { arg: number; unknown: string | boolean | null; twice: string | undefined; twices: any[] | null; first: () => void; newProperty: number | boolean | undefined; second: () => void; }
>unknown : string | boolean | null
>'hi' : "hi"
this.newProperty = 1 // ok: number | boolean
>this.newProperty = 1 : 1
>this.newProperty : number | boolean | undefined
>this : { arg: number; unknown: string | boolean | null; twice: string | undefined; twices: any[] | null; first: () => void; newProperty: number | boolean | undefined; second: () => void; }
>newProperty : number | boolean | undefined
>1 : 1
this.twice = undefined // ok
>this.twice = undefined : undefined
>this.twice : string | undefined
>this : { arg: number; unknown: string | boolean | null; twice: string | undefined; twices: any[] | null; first: () => void; newProperty: number | boolean | undefined; second: () => void; }
>twice : string | undefined
>undefined : undefined
this.twice = 'hi' // ok
>this.twice = 'hi' : "hi"
>this.twice : string | undefined
>this : { arg: number; unknown: string | boolean | null; twice: string | undefined; twices: any[] | null; first: () => void; newProperty: number | boolean | undefined; second: () => void; }
>twice : string | undefined
>'hi' : "hi"
}
Installer.prototype.second = function () {
>Installer.prototype.second = function () { this.arg = false // error this.unknown = false // ok this.newProperty = false // ok this.twice = null // error this.twice = false // error this.twices.push(1) // error: Object is possibly null if (this.twices != null) { this.twices.push('hi') }} : () => void
>Installer.prototype.second : any
>Installer.prototype : any
>Installer : () => void
>prototype : any
>second : any
>function () { this.arg = false // error this.unknown = false // ok this.newProperty = false // ok this.twice = null // error this.twice = false // error this.twices.push(1) // error: Object is possibly null if (this.twices != null) { this.twices.push('hi') }} : () => void
this.arg = false // error
>this.arg = false : false
>this.arg : number
>this : { arg: number; unknown: string | boolean | null; twice: string | undefined; twices: any[] | null; first: () => void; newProperty: number | boolean | undefined; second: () => void; }
>arg : number
>false : false
this.unknown = false // ok
>this.unknown = false : false
>this.unknown : string | boolean | null
>this : { arg: number; unknown: string | boolean | null; twice: string | undefined; twices: any[] | null; first: () => void; newProperty: number | boolean | undefined; second: () => void; }
>unknown : string | boolean | null
>false : false
this.newProperty = false // ok
>this.newProperty = false : false
>this.newProperty : number | boolean | undefined
>this : { arg: number; unknown: string | boolean | null; twice: string | undefined; twices: any[] | null; first: () => void; newProperty: number | boolean | undefined; second: () => void; }
>newProperty : number | boolean | undefined
>false : false
this.twice = null // error
>this.twice = null : null
>this.twice : string | undefined
>this : { arg: number; unknown: string | boolean | null; twice: string | undefined; twices: any[] | null; first: () => void; newProperty: number | boolean | undefined; second: () => void; }
>twice : string | undefined
>null : null
this.twice = false // error
>this.twice = false : false
>this.twice : string | undefined
>this : { arg: number; unknown: string | boolean | null; twice: string | undefined; twices: any[] | null; first: () => void; newProperty: number | boolean | undefined; second: () => void; }
>twice : string | undefined
>false : false
this.twices.push(1) // error: Object is possibly null
>this.twices.push(1) : number
>this.twices.push : (...items: any[]) => number
>this.twices : any[] | null
>this : { arg: number; unknown: string | boolean | null; twice: string | undefined; twices: any[] | null; first: () => void; newProperty: number | boolean | undefined; second: () => void; }
>twices : any[] | null
>push : (...items: any[]) => number
>1 : 1
if (this.twices != null) {
>this.twices != null : boolean
>this.twices : any[] | null
>this : { arg: number; unknown: string | boolean | null; twice: string | undefined; twices: any[] | null; first: () => void; newProperty: number | boolean | undefined; second: () => void; }
>twices : any[] | null
>null : null
this.twices.push('hi')
>this.twices.push('hi') : number
>this.twices.push : (...items: any[]) => number
>this.twices : any[]
>this : { arg: number; unknown: string | boolean | null; twice: string | undefined; twices: any[] | null; first: () => void; newProperty: number | boolean | undefined; second: () => void; }
>twices : any[]
>push : (...items: any[]) => number
>'hi' : "hi"
}
}

View File

@@ -0,0 +1,75 @@
tests/cases/conformance/salsa/a.js(3,5): error TS7008: Member 'unknown' implicitly has an 'any' type.
tests/cases/conformance/salsa/a.js(4,5): error TS7008: Member 'unknowable' implicitly has an 'any' type.
tests/cases/conformance/salsa/a.js(5,5): error TS7008: Member 'empty' implicitly has an 'any[]' type.
tests/cases/conformance/salsa/a.js(25,12): error TS7006: Parameter 'a' implicitly has an 'any' type.
tests/cases/conformance/salsa/a.js(25,29): error TS7006: Parameter 'l' implicitly has an 'any[]' type.
tests/cases/conformance/salsa/a.js(37,5): error TS2322: Type '"error"' is not assignable to type 'number | undefined'.
==== tests/cases/conformance/salsa/a.js (6 errors) ====
function A () {
// should get any on this-assignments in constructor
this.unknown = null
~~~~~~~~~~~~~~~~~~~
!!! error TS7008: Member 'unknown' implicitly has an 'any' type.
this.unknowable = undefined
~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS7008: Member 'unknowable' implicitly has an 'any' type.
this.empty = []
~~~~~~~~~~~~~~~
!!! error TS7008: Member 'empty' implicitly has an 'any[]' type.
}
var a = new A()
a.unknown = 1
a.unknown = true
a.unknown = {}
a.unknown = 'hi'
a.unknowable = 1
a.unknowable = true
a.unknowable = {}
a.unknowable = 'hi'
a.empty.push(1)
a.empty.push(true)
a.empty.push({})
a.empty.push('hi')
/** @type {number | undefined} */
var n;
// should get any on parameter initialisers
function f(a = null, b = n, l = []) {
~~~~~~~~
!!! error TS7006: Parameter 'a' implicitly has an 'any' type.
~~~~~~
!!! error TS7006: Parameter 'l' implicitly has an 'any[]' type.
// a should be any
a = undefined
a = null
a = 1
a = true
a = {}
a = 'ok'
// b should be number | undefined, not any
b = 1
b = undefined
b = 'error'
~
!!! error TS2322: Type '"error"' is not assignable to type 'number | undefined'.
// l should be any[]
l.push(1)
l.push('ok')
}
// should get any on variable initialisers
var u = undefined;
var l = [];
u = undefined
u = 1
u = true
u = {}
u = 'ok'
l.push('ok')

View File

@@ -0,0 +1,171 @@
=== tests/cases/conformance/salsa/a.js ===
function A () {
>A : Symbol(A, Decl(a.js, 0, 0))
// should get any on this-assignments in constructor
this.unknown = null
>unknown : Symbol(A.unknown, Decl(a.js, 0, 15))
this.unknowable = undefined
>unknowable : Symbol(A.unknowable, Decl(a.js, 2, 23))
>undefined : Symbol(undefined)
this.empty = []
>empty : Symbol(A.empty, Decl(a.js, 3, 31))
}
var a = new A()
>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16))
>A : Symbol(A, Decl(a.js, 0, 0))
a.unknown = 1
>a.unknown : Symbol(A.unknown, Decl(a.js, 0, 15))
>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16))
>unknown : Symbol(A.unknown, Decl(a.js, 0, 15))
a.unknown = true
>a.unknown : Symbol(A.unknown, Decl(a.js, 0, 15))
>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16))
>unknown : Symbol(A.unknown, Decl(a.js, 0, 15))
a.unknown = {}
>a.unknown : Symbol(A.unknown, Decl(a.js, 0, 15))
>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16))
>unknown : Symbol(A.unknown, Decl(a.js, 0, 15))
a.unknown = 'hi'
>a.unknown : Symbol(A.unknown, Decl(a.js, 0, 15))
>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16))
>unknown : Symbol(A.unknown, Decl(a.js, 0, 15))
a.unknowable = 1
>a.unknowable : Symbol(A.unknowable, Decl(a.js, 2, 23))
>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16))
>unknowable : Symbol(A.unknowable, Decl(a.js, 2, 23))
a.unknowable = true
>a.unknowable : Symbol(A.unknowable, Decl(a.js, 2, 23))
>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16))
>unknowable : Symbol(A.unknowable, Decl(a.js, 2, 23))
a.unknowable = {}
>a.unknowable : Symbol(A.unknowable, Decl(a.js, 2, 23))
>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16))
>unknowable : Symbol(A.unknowable, Decl(a.js, 2, 23))
a.unknowable = 'hi'
>a.unknowable : Symbol(A.unknowable, Decl(a.js, 2, 23))
>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16))
>unknowable : Symbol(A.unknowable, Decl(a.js, 2, 23))
a.empty.push(1)
>a.empty.push : Symbol(Array.push, Decl(lib.d.ts, --, --))
>a.empty : Symbol(A.empty, Decl(a.js, 3, 31))
>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16))
>empty : Symbol(A.empty, Decl(a.js, 3, 31))
>push : Symbol(Array.push, Decl(lib.d.ts, --, --))
a.empty.push(true)
>a.empty.push : Symbol(Array.push, Decl(lib.d.ts, --, --))
>a.empty : Symbol(A.empty, Decl(a.js, 3, 31))
>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16))
>empty : Symbol(A.empty, Decl(a.js, 3, 31))
>push : Symbol(Array.push, Decl(lib.d.ts, --, --))
a.empty.push({})
>a.empty.push : Symbol(Array.push, Decl(lib.d.ts, --, --))
>a.empty : Symbol(A.empty, Decl(a.js, 3, 31))
>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16))
>empty : Symbol(A.empty, Decl(a.js, 3, 31))
>push : Symbol(Array.push, Decl(lib.d.ts, --, --))
a.empty.push('hi')
>a.empty.push : Symbol(Array.push, Decl(lib.d.ts, --, --))
>a.empty : Symbol(A.empty, Decl(a.js, 3, 31))
>a : Symbol(a, Decl(a.js, 6, 3), Decl(a.js, 8, 16))
>empty : Symbol(A.empty, Decl(a.js, 3, 31))
>push : Symbol(Array.push, Decl(lib.d.ts, --, --))
/** @type {number | undefined} */
var n;
>n : Symbol(n, Decl(a.js, 21, 3))
// should get any on parameter initialisers
function f(a = null, b = n, l = []) {
>f : Symbol(f, Decl(a.js, 21, 6))
>a : Symbol(a, Decl(a.js, 24, 11))
>b : Symbol(b, Decl(a.js, 24, 20))
>n : Symbol(n, Decl(a.js, 21, 3))
>l : Symbol(l, Decl(a.js, 24, 27))
// a should be any
a = undefined
>a : Symbol(a, Decl(a.js, 24, 11))
>undefined : Symbol(undefined)
a = null
>a : Symbol(a, Decl(a.js, 24, 11))
a = 1
>a : Symbol(a, Decl(a.js, 24, 11))
a = true
>a : Symbol(a, Decl(a.js, 24, 11))
a = {}
>a : Symbol(a, Decl(a.js, 24, 11))
a = 'ok'
>a : Symbol(a, Decl(a.js, 24, 11))
// b should be number | undefined, not any
b = 1
>b : Symbol(b, Decl(a.js, 24, 20))
b = undefined
>b : Symbol(b, Decl(a.js, 24, 20))
>undefined : Symbol(undefined)
b = 'error'
>b : Symbol(b, Decl(a.js, 24, 20))
// l should be any[]
l.push(1)
>l.push : Symbol(Array.push, Decl(lib.d.ts, --, --))
>l : Symbol(l, Decl(a.js, 24, 27))
>push : Symbol(Array.push, Decl(lib.d.ts, --, --))
l.push('ok')
>l.push : Symbol(Array.push, Decl(lib.d.ts, --, --))
>l : Symbol(l, Decl(a.js, 24, 27))
>push : Symbol(Array.push, Decl(lib.d.ts, --, --))
}
// should get any on variable initialisers
var u = undefined;
>u : Symbol(u, Decl(a.js, 44, 3))
>undefined : Symbol(undefined)
var l = [];
>l : Symbol(l, Decl(a.js, 45, 3))
u = undefined
>u : Symbol(u, Decl(a.js, 44, 3))
>undefined : Symbol(undefined)
u = 1
>u : Symbol(u, Decl(a.js, 44, 3))
u = true
>u : Symbol(u, Decl(a.js, 44, 3))
u = {}
>u : Symbol(u, Decl(a.js, 44, 3))
u = 'ok'
>u : Symbol(u, Decl(a.js, 44, 3))
l.push('ok')
>l.push : Symbol(Array.push, Decl(lib.d.ts, --, --))
>l : Symbol(l, Decl(a.js, 45, 3))
>push : Symbol(Array.push, Decl(lib.d.ts, --, --))

View File

@@ -0,0 +1,241 @@
=== tests/cases/conformance/salsa/a.js ===
function A () {
>A : () => void
// should get any on this-assignments in constructor
this.unknown = null
>this.unknown = null : null
>this.unknown : any
>this : any
>unknown : any
>null : null
this.unknowable = undefined
>this.unknowable = undefined : undefined
>this.unknowable : any
>this : any
>unknowable : any
>undefined : undefined
this.empty = []
>this.empty = [] : never[]
>this.empty : any
>this : any
>empty : any
>[] : never[]
}
var a = new A()
>a : { unknown: any; unknowable: any; empty: any[]; }
>new A() : { unknown: any; unknowable: any; empty: any[]; }
>A : () => void
a.unknown = 1
>a.unknown = 1 : 1
>a.unknown : any
>a : { unknown: any; unknowable: any; empty: any[]; }
>unknown : any
>1 : 1
a.unknown = true
>a.unknown = true : true
>a.unknown : any
>a : { unknown: any; unknowable: any; empty: any[]; }
>unknown : any
>true : true
a.unknown = {}
>a.unknown = {} : { [x: string]: any; }
>a.unknown : any
>a : { unknown: any; unknowable: any; empty: any[]; }
>unknown : any
>{} : { [x: string]: any; }
a.unknown = 'hi'
>a.unknown = 'hi' : "hi"
>a.unknown : any
>a : { unknown: any; unknowable: any; empty: any[]; }
>unknown : any
>'hi' : "hi"
a.unknowable = 1
>a.unknowable = 1 : 1
>a.unknowable : any
>a : { unknown: any; unknowable: any; empty: any[]; }
>unknowable : any
>1 : 1
a.unknowable = true
>a.unknowable = true : true
>a.unknowable : any
>a : { unknown: any; unknowable: any; empty: any[]; }
>unknowable : any
>true : true
a.unknowable = {}
>a.unknowable = {} : { [x: string]: any; }
>a.unknowable : any
>a : { unknown: any; unknowable: any; empty: any[]; }
>unknowable : any
>{} : { [x: string]: any; }
a.unknowable = 'hi'
>a.unknowable = 'hi' : "hi"
>a.unknowable : any
>a : { unknown: any; unknowable: any; empty: any[]; }
>unknowable : any
>'hi' : "hi"
a.empty.push(1)
>a.empty.push(1) : number
>a.empty.push : (...items: any[]) => number
>a.empty : any[]
>a : { unknown: any; unknowable: any; empty: any[]; }
>empty : any[]
>push : (...items: any[]) => number
>1 : 1
a.empty.push(true)
>a.empty.push(true) : number
>a.empty.push : (...items: any[]) => number
>a.empty : any[]
>a : { unknown: any; unknowable: any; empty: any[]; }
>empty : any[]
>push : (...items: any[]) => number
>true : true
a.empty.push({})
>a.empty.push({}) : number
>a.empty.push : (...items: any[]) => number
>a.empty : any[]
>a : { unknown: any; unknowable: any; empty: any[]; }
>empty : any[]
>push : (...items: any[]) => number
>{} : {}
a.empty.push('hi')
>a.empty.push('hi') : number
>a.empty.push : (...items: any[]) => number
>a.empty : any[]
>a : { unknown: any; unknowable: any; empty: any[]; }
>empty : any[]
>push : (...items: any[]) => number
>'hi' : "hi"
/** @type {number | undefined} */
var n;
>n : number | undefined
// should get any on parameter initialisers
function f(a = null, b = n, l = []) {
>f : (a?: any, b?: number | undefined, l?: any[]) => void
>a : any
>null : null
>b : number | undefined
>n : number | undefined
>l : any[]
>[] : never[]
// a should be any
a = undefined
>a = undefined : undefined
>a : any
>undefined : undefined
a = null
>a = null : null
>a : any
>null : null
a = 1
>a = 1 : 1
>a : any
>1 : 1
a = true
>a = true : true
>a : any
>true : true
a = {}
>a = {} : {}
>a : any
>{} : {}
a = 'ok'
>a = 'ok' : "ok"
>a : any
>'ok' : "ok"
// b should be number | undefined, not any
b = 1
>b = 1 : 1
>b : number | undefined
>1 : 1
b = undefined
>b = undefined : undefined
>b : number | undefined
>undefined : undefined
b = 'error'
>b = 'error' : "error"
>b : number | undefined
>'error' : "error"
// l should be any[]
l.push(1)
>l.push(1) : number
>l.push : (...items: any[]) => number
>l : any[]
>push : (...items: any[]) => number
>1 : 1
l.push('ok')
>l.push('ok') : number
>l.push : (...items: any[]) => number
>l : any[]
>push : (...items: any[]) => number
>'ok' : "ok"
}
// should get any on variable initialisers
var u = undefined;
>u : any
>undefined : undefined
var l = [];
>l : any[]
>[] : never[]
u = undefined
>u = undefined : undefined
>u : any
>undefined : undefined
u = 1
>u = 1 : 1
>u : any
>1 : 1
u = true
>u = true : true
>u : any
>true : true
u = {}
>u = {} : {}
>u : any
>{} : {}
u = 'ok'
>u = 'ok' : "ok"
>u : any
>'ok' : "ok"
l.push('ok')
>l.push('ok') : number
>l.push : (...items: any[]) => number
>l : any[]
>push : (...items: any[]) => number
>'ok' : "ok"

View File

@@ -1,5 +1,4 @@
tests/cases/conformance/salsa/npm-install.js(12,1): error TS2322: Type 'string | number' is not assignable to type 'number | undefined'.
Type 'string' is not assignable to type 'number | undefined'.
tests/cases/conformance/salsa/npm-install.js(7,9): error TS2322: Type '"hi"' is not assignable to type 'number'.
==== tests/cases/conformance/salsa/npm-install.js (1 errors) ====
@@ -10,12 +9,11 @@ tests/cases/conformance/salsa/npm-install.js(12,1): error TS2322: Type 'string |
// ArrowFunction isn't treated as a this-container
(args) => {
this.args = 'hi'
~~~~~~~~~
!!! error TS2322: Type '"hi"' is not assignable to type 'number'.
this.newProperty = 1
}
}
var i = new Installer()
i.newProperty = i.args // error, number | string =/> number | undefined
~~~~~~~~~~~~~
!!! error TS2322: Type 'string | number' is not assignable to type 'number | undefined'.
!!! error TS2322: Type 'string' is not assignable to type 'number | undefined'.
i.newProperty = i.args // ok, number ==> number | undefined

View File

@@ -31,7 +31,7 @@ var i = new Installer()
>i : Symbol(i, Decl(npm-install.js, 10, 3))
>Installer : Symbol(Installer, Decl(npm-install.js, 0, 0))
i.newProperty = i.args // error, number | string =/> number | undefined
i.newProperty = i.args // ok, number ==> number | undefined
>i.newProperty : Symbol(Installer.newProperty, Decl(npm-install.js, 6, 24))
>i : Symbol(i, Decl(npm-install.js, 10, 3))
>newProperty : Symbol(Installer.newProperty, Decl(npm-install.js, 6, 24))

View File

@@ -26,30 +26,30 @@ Installer.prototype.loadArgMetadata = function (next) {
this.args = 'hi'
>this.args = 'hi' : "hi"
>this.args : string | number
>this : { args: string | number; loadArgMetadata: (next: any) => void; newProperty: number | undefined; }
>args : string | number
>this.args : number
>this : { args: number; loadArgMetadata: (next: any) => void; newProperty: number | undefined; }
>args : number
>'hi' : "hi"
this.newProperty = 1
>this.newProperty = 1 : 1
>this.newProperty : number | undefined
>this : { args: string | number; loadArgMetadata: (next: any) => void; newProperty: number | undefined; }
>this : { args: number; loadArgMetadata: (next: any) => void; newProperty: number | undefined; }
>newProperty : number | undefined
>1 : 1
}
}
var i = new Installer()
>i : { args: string | number; loadArgMetadata: (next: any) => void; newProperty: number | undefined; }
>new Installer() : { args: string | number; loadArgMetadata: (next: any) => void; newProperty: number | undefined; }
>i : { args: number; loadArgMetadata: (next: any) => void; newProperty: number | undefined; }
>new Installer() : { args: number; loadArgMetadata: (next: any) => void; newProperty: number | undefined; }
>Installer : () => void
i.newProperty = i.args // error, number | string =/> number | undefined
>i.newProperty = i.args : string | number
i.newProperty = i.args // ok, number ==> number | undefined
>i.newProperty = i.args : number
>i.newProperty : number | undefined
>i : { args: string | number; loadArgMetadata: (next: any) => void; newProperty: number | undefined; }
>i : { args: number; loadArgMetadata: (next: any) => void; newProperty: number | undefined; }
>newProperty : number | undefined
>i.args : string | number
>i : { args: string | number; loadArgMetadata: (next: any) => void; newProperty: number | undefined; }
>args : string | number
>i.args : number
>i : { args: number; loadArgMetadata: (next: any) => void; newProperty: number | undefined; }
>args : number

View File

@@ -1,5 +1,7 @@
// @out: output.js
// @allowJs: true
// @checkJs: true
// @noImplicitAny: true
// @strictNullChecks: true
// @filename: a.js
@@ -16,11 +18,14 @@ class C {
method() {
if (Math.random()) {
this.inMethod = 0;
this.inMethodNullable = null;
}
else {
this.inMethod = "string"
this.inMethodNullable = undefined;
}
this.inMultiple = "string";
this.inMultipleMethods = "string";
var action = () => {
if (Math.random()) {
@@ -39,6 +44,7 @@ class C {
this.inGetter = "string"
}
this.inMultiple = false;
this.inMultipleMethods = false;
}
set() {
if (Math.random()) {
@@ -115,7 +121,12 @@ var stringOrNumberOrUndefined = c.inNestedArrowFunction
var stringOrNumberOrBoolean: string | number | boolean;
var stringOrNumberOrBoolean = c.inMultiple;
var number: number;
var number = c.inMultiple;
var stringOrBooleanOrUndefined : string | boolean | undefined;
var stringOrBooleanOrUndefined = c.inMultipleMethods;
var any: any;
var any = c.inMethodNullable;
var stringOrNumberOrUndefined = C.inStaticMethod;

View File

@@ -0,0 +1,36 @@
// @allowJs: true
// @checkJs: true
// @noEmit: true
// @strictNullChecks: true
// @noImplicitAny: true
// @Filename: a.js
function Installer () {
// arg: number
this.arg = 0
// unknown: string | boolean | null
this.unknown = null
// twice: string | undefined
this.twice = undefined
this.twice = 'hi'
// twices: any[] | null
this.twices = []
this.twices = null
}
Installer.prototype.first = function () {
this.arg = 'hi' // error
this.unknown = 'hi' // ok
this.newProperty = 1 // ok: number | boolean
this.twice = undefined // ok
this.twice = 'hi' // ok
}
Installer.prototype.second = function () {
this.arg = false // error
this.unknown = false // ok
this.newProperty = false // ok
this.twice = null // error
this.twice = false // error
this.twices.push(1) // error: Object is possibly null
if (this.twices != null) {
this.twices.push('hi')
}
}

View File

@@ -0,0 +1,59 @@
// @allowJs: true
// @checkJs: true
// @noEmit: true
// @strictNullChecks: true
// @noImplicitAny: true
// @Filename: a.js
function A () {
// should get any on this-assignments in constructor
this.unknown = null
this.unknowable = undefined
this.empty = []
}
var a = new A()
a.unknown = 1
a.unknown = true
a.unknown = {}
a.unknown = 'hi'
a.unknowable = 1
a.unknowable = true
a.unknowable = {}
a.unknowable = 'hi'
a.empty.push(1)
a.empty.push(true)
a.empty.push({})
a.empty.push('hi')
/** @type {number | undefined} */
var n;
// should get any on parameter initialisers
function f(a = null, b = n, l = []) {
// a should be any
a = undefined
a = null
a = 1
a = true
a = {}
a = 'ok'
// b should be number | undefined, not any
b = 1
b = undefined
b = 'error'
// l should be any[]
l.push(1)
l.push('ok')
}
// should get any on variable initialisers
var u = undefined;
var l = [];
u = undefined
u = 1
u = true
u = {}
u = 'ok'
l.push('ok')

View File

@@ -14,4 +14,4 @@ Installer.prototype.loadArgMetadata = function (next) {
}
}
var i = new Installer()
i.newProperty = i.args // error, number | string =/> number | undefined
i.newProperty = i.args // ok, number ==> number | undefined