Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19054,6 +19054,8 @@ namespace ts {
return getExplicitTypeOfSymbol(symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol, diagnostic);
case SyntaxKind.ThisKeyword:
return getExplicitThisType(node);
case SyntaxKind.SuperKeyword:
return checkSuperExpression(node);
case SyntaxKind.PropertyAccessExpression:
const type = getTypeOfDottedName((<PropertyAccessExpression>node).expression, diagnostic);
const prop = type && getPropertyOfType(type, (<PropertyAccessExpression>node).name.escapedText);
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4278,7 +4278,7 @@ namespace ts {
}

export function isDottedName(node: Expression): boolean {
return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.ThisKeyword ||
return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.ThisKeyword || node.kind === SyntaxKind.SuperKeyword ||
node.kind === SyntaxKind.PropertyAccessExpression && isDottedName((<PropertyAccessExpression>node).expression) ||
node.kind === SyntaxKind.ParenthesizedExpression && isDottedName((<ParenthesizedExpression>node).expression);
}
Expand Down
40 changes: 27 additions & 13 deletions tests/baselines/reference/assertionTypePredicates1.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@ tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(39,9): error TS7
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(43,9): error TS7027: Unreachable code detected.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(87,9): error TS7027: Unreachable code detected.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(122,9): error TS7027: Unreachable code detected.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(132,37): error TS1228: A type predicate is only allowed in return type position for functions and methods.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(133,37): error TS1228: A type predicate is only allowed in return type position for functions and methods.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(134,37): error TS1228: A type predicate is only allowed in return type position for functions and methods.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(137,15): error TS1228: A type predicate is only allowed in return type position for functions and methods.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(138,15): error TS1228: A type predicate is only allowed in return type position for functions and methods.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(139,15): error TS1228: A type predicate is only allowed in return type position for functions and methods.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(140,15): error TS1228: A type predicate is only allowed in return type position for functions and methods.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(145,5): error TS2775: Assertions require every name in the call target to be declared with an explicit type annotation.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(147,5): error TS2776: Assertions require the call target to be an identifier or qualified name.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(149,5): error TS2775: Assertions require every name in the call target to be declared with an explicit type annotation.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(137,9): error TS7027: Unreachable code detected.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(143,37): error TS1228: A type predicate is only allowed in return type position for functions and methods.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(144,37): error TS1228: A type predicate is only allowed in return type position for functions and methods.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(145,37): error TS1228: A type predicate is only allowed in return type position for functions and methods.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(148,15): error TS1228: A type predicate is only allowed in return type position for functions and methods.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(149,15): error TS1228: A type predicate is only allowed in return type position for functions and methods.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(150,15): error TS1228: A type predicate is only allowed in return type position for functions and methods.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(151,15): error TS1228: A type predicate is only allowed in return type position for functions and methods.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(156,5): error TS2775: Assertions require every name in the call target to be declared with an explicit type annotation.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(158,5): error TS2776: Assertions require the call target to be an identifier or qualified name.
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(160,5): error TS2775: Assertions require every name in the call target to be declared with an explicit type annotation.


==== tests/cases/conformance/controlFlow/assertionTypePredicates1.ts (14 errors) ====
==== tests/cases/conformance/controlFlow/assertionTypePredicates1.ts (15 errors) ====
declare function isString(value: unknown): value is string;
declare function isArrayOfStrings(value: unknown): value is string[];

Expand Down Expand Up @@ -152,6 +153,19 @@ tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(149,5): error TS
z = 0;
}

class Derived extends Test {
foo(x: unknown) {
super.assert(typeof x === "string");
x.length;
}
baz(x: number) {
super.assert(false);
x; // Unreachable
~~
!!! error TS7027: Unreachable code detected.
}
}

// Invalid constructs

declare let Q1: new (x: unknown) => x is string;
Expand Down Expand Up @@ -184,7 +198,7 @@ tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(149,5): error TS
assert(typeof x === "string"); // Error
~~~~~~
!!! error TS2775: Assertions require every name in the call target to be declared with an explicit type annotation.
!!! related TS2782 tests/cases/conformance/controlFlow/assertionTypePredicates1.ts:144:11: 'assert' needs an explicit type annotation.
!!! related TS2782 tests/cases/conformance/controlFlow/assertionTypePredicates1.ts:155:11: 'assert' needs an explicit type annotation.
const a = [assert];
a[0](typeof x === "string"); // Error
~~~~
Expand All @@ -193,7 +207,7 @@ tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(149,5): error TS
t1.assert(typeof x === "string"); // Error
~~~~~~~~~
!!! error TS2775: Assertions require every name in the call target to be declared with an explicit type annotation.
!!! related TS2782 tests/cases/conformance/controlFlow/assertionTypePredicates1.ts:148:11: 't1' needs an explicit type annotation.
!!! related TS2782 tests/cases/conformance/controlFlow/assertionTypePredicates1.ts:159:11: 't1' needs an explicit type annotation.
const t2: Test = new Test();
t2.assert(typeof x === "string");
}
Expand Down
30 changes: 30 additions & 0 deletions tests/baselines/reference/assertionTypePredicates1.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,17 @@ class Test2 extends Test {
z = 0;
}

class Derived extends Test {
foo(x: unknown) {
super.assert(typeof x === "string");
x.length;
}
baz(x: number) {
super.assert(false);
x; // Unreachable
}
}

// Invalid constructs

declare let Q1: new (x: unknown) => x is string;
Expand Down Expand Up @@ -293,6 +304,21 @@ var Test2 = /** @class */ (function (_super) {
}
return Test2;
}(Test));
var Derived = /** @class */ (function (_super) {
__extends(Derived, _super);
function Derived() {
return _super !== null && _super.apply(this, arguments) || this;
}
Derived.prototype.foo = function (x) {
_super.prototype.assert.call(this, typeof x === "string");
x.length;
};
Derived.prototype.baz = function (x) {
_super.prototype.assert.call(this, false);
x; // Unreachable
};
return Derived;
}(Test));
function f20(x) {
var assert = function (value) { };
assert(typeof x === "string"); // Error
Expand Down Expand Up @@ -332,6 +358,10 @@ declare class Test {
declare class Test2 extends Test {
z: number;
}
declare class Derived extends Test {
foo(x: unknown): void;
baz(x: number): void;
}
declare let Q1: new (x: unknown) => x is string;
declare let Q2: new (x: boolean) => asserts x;
declare let Q3: new (x: unknown) => asserts x is string;
Expand Down
99 changes: 66 additions & 33 deletions tests/baselines/reference/assertionTypePredicates1.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -359,81 +359,114 @@ class Test2 extends Test {
>z : Symbol(Test2.z, Decl(assertionTypePredicates1.ts, 125, 26))
}

class Derived extends Test {
>Derived : Symbol(Derived, Decl(assertionTypePredicates1.ts, 127, 1))
>Test : Symbol(Test, Decl(assertionTypePredicates1.ts, 88, 1))

foo(x: unknown) {
>foo : Symbol(Derived.foo, Decl(assertionTypePredicates1.ts, 129, 28))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 130, 8))

super.assert(typeof x === "string");
>super.assert : Symbol(Test.assert, Decl(assertionTypePredicates1.ts, 90, 12))
>super : Symbol(Test, Decl(assertionTypePredicates1.ts, 88, 1))
>assert : Symbol(Test.assert, Decl(assertionTypePredicates1.ts, 90, 12))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 130, 8))

x.length;
>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 130, 8))
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
}
baz(x: number) {
>baz : Symbol(Derived.baz, Decl(assertionTypePredicates1.ts, 133, 5))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 134, 8))

super.assert(false);
>super.assert : Symbol(Test.assert, Decl(assertionTypePredicates1.ts, 90, 12))
>super : Symbol(Test, Decl(assertionTypePredicates1.ts, 88, 1))
>assert : Symbol(Test.assert, Decl(assertionTypePredicates1.ts, 90, 12))

x; // Unreachable
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 134, 8))
}
}

// Invalid constructs

declare let Q1: new (x: unknown) => x is string;
>Q1 : Symbol(Q1, Decl(assertionTypePredicates1.ts, 131, 11))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 131, 21))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 131, 21))
>Q1 : Symbol(Q1, Decl(assertionTypePredicates1.ts, 142, 11))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 142, 21))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 142, 21))

declare let Q2: new (x: boolean) => asserts x;
>Q2 : Symbol(Q2, Decl(assertionTypePredicates1.ts, 132, 11))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 132, 21))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 132, 21))
>Q2 : Symbol(Q2, Decl(assertionTypePredicates1.ts, 143, 11))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 143, 21))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 143, 21))

declare let Q3: new (x: unknown) => asserts x is string;
>Q3 : Symbol(Q3, Decl(assertionTypePredicates1.ts, 133, 11))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 133, 21))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 133, 21))
>Q3 : Symbol(Q3, Decl(assertionTypePredicates1.ts, 144, 11))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 144, 21))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 144, 21))

declare class Wat {
>Wat : Symbol(Wat, Decl(assertionTypePredicates1.ts, 133, 56))
>Wat : Symbol(Wat, Decl(assertionTypePredicates1.ts, 144, 56))

get p1(): this is string;
>p1 : Symbol(Wat.p1, Decl(assertionTypePredicates1.ts, 135, 19), Decl(assertionTypePredicates1.ts, 136, 29))
>p1 : Symbol(Wat.p1, Decl(assertionTypePredicates1.ts, 146, 19), Decl(assertionTypePredicates1.ts, 147, 29))

set p1(x: this is string);
>p1 : Symbol(Wat.p1, Decl(assertionTypePredicates1.ts, 135, 19), Decl(assertionTypePredicates1.ts, 136, 29))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 137, 11))
>p1 : Symbol(Wat.p1, Decl(assertionTypePredicates1.ts, 146, 19), Decl(assertionTypePredicates1.ts, 147, 29))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 148, 11))

get p2(): asserts this is string;
>p2 : Symbol(Wat.p2, Decl(assertionTypePredicates1.ts, 137, 30), Decl(assertionTypePredicates1.ts, 138, 37))
>p2 : Symbol(Wat.p2, Decl(assertionTypePredicates1.ts, 148, 30), Decl(assertionTypePredicates1.ts, 149, 37))

set p2(x: asserts this is string);
>p2 : Symbol(Wat.p2, Decl(assertionTypePredicates1.ts, 137, 30), Decl(assertionTypePredicates1.ts, 138, 37))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 139, 11))
>p2 : Symbol(Wat.p2, Decl(assertionTypePredicates1.ts, 148, 30), Decl(assertionTypePredicates1.ts, 149, 37))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 150, 11))
}

function f20(x: unknown) {
>f20 : Symbol(f20, Decl(assertionTypePredicates1.ts, 140, 1))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 142, 13))
>f20 : Symbol(f20, Decl(assertionTypePredicates1.ts, 151, 1))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 153, 13))

const assert = (value: unknown): asserts value => {}
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 143, 9))
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 143, 20))
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 143, 20))
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 154, 9))
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 154, 20))
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 154, 20))

assert(typeof x === "string"); // Error
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 143, 9))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 142, 13))
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 154, 9))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 153, 13))

const a = [assert];
>a : Symbol(a, Decl(assertionTypePredicates1.ts, 145, 9))
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 143, 9))
>a : Symbol(a, Decl(assertionTypePredicates1.ts, 156, 9))
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 154, 9))

a[0](typeof x === "string"); // Error
>a : Symbol(a, Decl(assertionTypePredicates1.ts, 145, 9))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 142, 13))
>a : Symbol(a, Decl(assertionTypePredicates1.ts, 156, 9))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 153, 13))

const t1 = new Test();
>t1 : Symbol(t1, Decl(assertionTypePredicates1.ts, 147, 9))
>t1 : Symbol(t1, Decl(assertionTypePredicates1.ts, 158, 9))
>Test : Symbol(Test, Decl(assertionTypePredicates1.ts, 88, 1))

t1.assert(typeof x === "string"); // Error
>t1.assert : Symbol(Test.assert, Decl(assertionTypePredicates1.ts, 90, 12))
>t1 : Symbol(t1, Decl(assertionTypePredicates1.ts, 147, 9))
>t1 : Symbol(t1, Decl(assertionTypePredicates1.ts, 158, 9))
>assert : Symbol(Test.assert, Decl(assertionTypePredicates1.ts, 90, 12))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 142, 13))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 153, 13))

const t2: Test = new Test();
>t2 : Symbol(t2, Decl(assertionTypePredicates1.ts, 149, 9))
>t2 : Symbol(t2, Decl(assertionTypePredicates1.ts, 160, 9))
>Test : Symbol(Test, Decl(assertionTypePredicates1.ts, 88, 1))
>Test : Symbol(Test, Decl(assertionTypePredicates1.ts, 88, 1))

t2.assert(typeof x === "string");
>t2.assert : Symbol(Test.assert, Decl(assertionTypePredicates1.ts, 90, 12))
>t2 : Symbol(t2, Decl(assertionTypePredicates1.ts, 149, 9))
>t2 : Symbol(t2, Decl(assertionTypePredicates1.ts, 160, 9))
>assert : Symbol(Test.assert, Decl(assertionTypePredicates1.ts, 90, 12))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 142, 13))
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 153, 13))
}

39 changes: 39 additions & 0 deletions tests/baselines/reference/assertionTypePredicates1.types
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,45 @@ class Test2 extends Test {
>0 : 0
}

class Derived extends Test {
>Derived : Derived
>Test : Test

foo(x: unknown) {
>foo : (x: unknown) => void
>x : unknown

super.assert(typeof x === "string");
>super.assert(typeof x === "string") : void
>super.assert : (value: unknown) => asserts value
>super : Test
>assert : (value: unknown) => asserts value
>typeof x === "string" : boolean
>typeof x : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
>x : unknown
>"string" : "string"

x.length;
>x.length : number
>x : string
>length : number
}
baz(x: number) {
>baz : (x: number) => void
>x : number

super.assert(false);
>super.assert(false) : void
>super.assert : (value: unknown) => asserts value
>super : Test
>assert : (value: unknown) => asserts value
>false : false

x; // Unreachable
>x : number
}
}

// Invalid constructs

declare let Q1: new (x: unknown) => x is string;
Expand Down
17 changes: 17 additions & 0 deletions tests/baselines/reference/neverReturningFunctions1.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -301,4 +301,21 @@ tests/cases/conformance/controlFlow/neverReturningFunctions1.ts(153,5): error TS
return f * this.data.num * this.system!.data.counter;
}
});

// Repro from #36147

class MyThrowable {
throw(): never {
throw new Error();
}
}

class SuperThrowable extends MyThrowable {
err(msg: string): never {
super.throw()
}
ok(): never {
this.throw()
}
}

Loading