Support for/of variables in assertion checking (#37432)
* Support for/of variables in assertion checking * Integrate with "dotted name" logic * Add tests
This commit is contained in:
parent
c8e43d878f
commit
0222211acb
|
@ -7266,7 +7266,7 @@ namespace ts {
|
|||
// [Symbol.iterator] or next). This may be because we accessed properties from anyType,
|
||||
// or it may have led to an error inside getElementTypeOfIterable.
|
||||
const forOfStatement = declaration.parent.parent;
|
||||
return checkRightHandSideOfForOf(forOfStatement.expression, forOfStatement.awaitModifier) || anyType;
|
||||
return checkRightHandSideOfForOf(forOfStatement) || anyType;
|
||||
}
|
||||
|
||||
if (isBindingPattern(declaration.parent)) {
|
||||
|
@ -19204,7 +19204,7 @@ namespace ts {
|
|||
case SyntaxKind.ForInStatement:
|
||||
return stringType;
|
||||
case SyntaxKind.ForOfStatement:
|
||||
return checkRightHandSideOfForOf((<ForOfStatement>parent).expression, (<ForOfStatement>parent).awaitModifier) || errorType;
|
||||
return checkRightHandSideOfForOf(<ForOfStatement>parent) || errorType;
|
||||
case SyntaxKind.BinaryExpression:
|
||||
return getAssignedTypeOfBinaryExpression(<BinaryExpression>parent);
|
||||
case SyntaxKind.DeleteExpression:
|
||||
|
@ -19248,7 +19248,7 @@ namespace ts {
|
|||
return stringType;
|
||||
}
|
||||
if (node.parent.parent.kind === SyntaxKind.ForOfStatement) {
|
||||
return checkRightHandSideOfForOf(node.parent.parent.expression, node.parent.parent.awaitModifier) || errorType;
|
||||
return checkRightHandSideOfForOf(node.parent.parent) || errorType;
|
||||
}
|
||||
return errorType;
|
||||
}
|
||||
|
@ -19513,11 +19513,10 @@ namespace ts {
|
|||
return isLengthPushOrUnshift || isElementAssignment;
|
||||
}
|
||||
|
||||
function isDeclarationWithExplicitTypeAnnotation(declaration: Declaration | undefined) {
|
||||
return !!(declaration && (
|
||||
declaration.kind === SyntaxKind.VariableDeclaration || declaration.kind === SyntaxKind.Parameter ||
|
||||
function isDeclarationWithExplicitTypeAnnotation(declaration: Declaration) {
|
||||
return (declaration.kind === SyntaxKind.VariableDeclaration || declaration.kind === SyntaxKind.Parameter ||
|
||||
declaration.kind === SyntaxKind.PropertyDeclaration || declaration.kind === SyntaxKind.PropertySignature) &&
|
||||
getEffectiveTypeAnnotationNode(declaration as VariableDeclaration | ParameterDeclaration | PropertyDeclaration | PropertySignature));
|
||||
!!getEffectiveTypeAnnotationNode(declaration as VariableDeclaration | ParameterDeclaration | PropertyDeclaration | PropertySignature);
|
||||
}
|
||||
|
||||
function getExplicitTypeOfSymbol(symbol: Symbol, diagnostic?: Diagnostic) {
|
||||
|
@ -19525,11 +19524,20 @@ namespace ts {
|
|||
return getTypeOfSymbol(symbol);
|
||||
}
|
||||
if (symbol.flags & (SymbolFlags.Variable | SymbolFlags.Property)) {
|
||||
if (isDeclarationWithExplicitTypeAnnotation(symbol.valueDeclaration)) {
|
||||
return getTypeOfSymbol(symbol);
|
||||
}
|
||||
if (diagnostic && symbol.valueDeclaration) {
|
||||
addRelatedInfo(diagnostic, createDiagnosticForNode(symbol.valueDeclaration, Diagnostics._0_needs_an_explicit_type_annotation, symbolToString(symbol)));
|
||||
const declaration = symbol.valueDeclaration;
|
||||
if (declaration) {
|
||||
if (isDeclarationWithExplicitTypeAnnotation(declaration)) {
|
||||
return getTypeOfSymbol(symbol);
|
||||
}
|
||||
if (isVariableDeclaration(declaration) && declaration.parent.parent.kind === SyntaxKind.ForOfStatement) {
|
||||
const expressionType = getTypeOfDottedName(declaration.parent.parent.expression, /*diagnostic*/ undefined);
|
||||
if (expressionType) {
|
||||
return getForOfIterationType(declaration.parent.parent, expressionType);
|
||||
}
|
||||
}
|
||||
if (diagnostic) {
|
||||
addRelatedInfo(diagnostic, createDiagnosticForNode(declaration, Diagnostics._0_needs_an_explicit_type_annotation, symbolToString(symbol)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31585,7 +31593,7 @@ namespace ts {
|
|||
}
|
||||
else {
|
||||
const varExpr = node.initializer;
|
||||
const iteratedType = checkRightHandSideOfForOf(node.expression, node.awaitModifier);
|
||||
const iteratedType = checkRightHandSideOfForOf(node);
|
||||
|
||||
// There may be a destructuring assignment on the left side
|
||||
if (varExpr.kind === SyntaxKind.ArrayLiteralExpression || varExpr.kind === SyntaxKind.ObjectLiteralExpression) {
|
||||
|
@ -31677,10 +31685,13 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function checkRightHandSideOfForOf(rhsExpression: Expression, awaitModifier: AwaitKeywordToken | undefined): Type {
|
||||
const expressionType = checkNonNullExpression(rhsExpression);
|
||||
const use = awaitModifier ? IterationUse.ForAwaitOf : IterationUse.ForOf;
|
||||
return checkIteratedTypeOrElementType(use, expressionType, undefinedType, rhsExpression);
|
||||
function checkRightHandSideOfForOf(statement: ForOfStatement): Type {
|
||||
return getForOfIterationType(statement, checkNonNullExpression(statement.expression));
|
||||
}
|
||||
|
||||
function getForOfIterationType(statement: ForOfStatement, expressionType: Type) {
|
||||
const use = statement.awaitModifier ? IterationUse.ForAwaitOf : IterationUse.ForOf;
|
||||
return checkIteratedTypeOrElementType(use, expressionType, undefinedType, statement.expression);
|
||||
}
|
||||
|
||||
function checkIteratedTypeOrElementType(use: IterationUse, inputType: Type, sentType: Type, errorNode: Node | undefined): Type {
|
||||
|
@ -35046,7 +35057,7 @@ namespace ts {
|
|||
// for ( { a } of elems) {
|
||||
// }
|
||||
if (expr.parent.kind === SyntaxKind.ForOfStatement) {
|
||||
const iteratedType = checkRightHandSideOfForOf((<ForOfStatement>expr.parent).expression, (<ForOfStatement>expr.parent).awaitModifier);
|
||||
const iteratedType = checkRightHandSideOfForOf(<ForOfStatement>expr.parent);
|
||||
return checkDestructuringAssignment(expr, iteratedType || errorType);
|
||||
}
|
||||
// If this is from "for" initializer
|
||||
|
|
|
@ -3,16 +3,16 @@ tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(43,9): error TS7
|
|||
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(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(153,37): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(154,37): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(155,37): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(158,15): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(159,15): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(160,15): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(161,15): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(166,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(168,5): error TS2776: Assertions require the call target to be an identifier or qualified name.
|
||||
tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(170,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 (15 errors) ====
|
||||
|
@ -166,6 +166,16 @@ tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(160,5): error TS
|
|||
}
|
||||
}
|
||||
|
||||
function f11(items: Test[]) {
|
||||
for (let item of items) {
|
||||
if (item.isTest2()) {
|
||||
item.z;
|
||||
}
|
||||
item.assertIsTest2();
|
||||
item.z;
|
||||
}
|
||||
}
|
||||
|
||||
// Invalid constructs
|
||||
|
||||
declare let Q1: new (x: unknown) => x is string;
|
||||
|
@ -198,7 +208,7 @@ tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(160,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:155:11: 'assert' needs an explicit type annotation.
|
||||
!!! related TS2782 tests/cases/conformance/controlFlow/assertionTypePredicates1.ts:165:11: 'assert' needs an explicit type annotation.
|
||||
const a = [assert];
|
||||
a[0](typeof x === "string"); // Error
|
||||
~~~~
|
||||
|
@ -207,8 +217,26 @@ tests/cases/conformance/controlFlow/assertionTypePredicates1.ts(160,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:159:11: 't1' needs an explicit type annotation.
|
||||
!!! related TS2782 tests/cases/conformance/controlFlow/assertionTypePredicates1.ts:169:11: 't1' needs an explicit type annotation.
|
||||
const t2: Test = new Test();
|
||||
t2.assert(typeof x === "string");
|
||||
}
|
||||
|
||||
// Repro from #35940
|
||||
|
||||
interface Thing {
|
||||
good: boolean;
|
||||
isGood(): asserts this is GoodThing;
|
||||
}
|
||||
|
||||
interface GoodThing {
|
||||
good: true;
|
||||
}
|
||||
|
||||
function example1(things: Thing[]) {
|
||||
for (let thing of things) {
|
||||
thing.isGood();
|
||||
thing.good;
|
||||
}
|
||||
}
|
||||
|
|
@ -139,6 +139,16 @@ class Derived extends Test {
|
|||
}
|
||||
}
|
||||
|
||||
function f11(items: Test[]) {
|
||||
for (let item of items) {
|
||||
if (item.isTest2()) {
|
||||
item.z;
|
||||
}
|
||||
item.assertIsTest2();
|
||||
item.z;
|
||||
}
|
||||
}
|
||||
|
||||
// Invalid constructs
|
||||
|
||||
declare let Q1: new (x: unknown) => x is string;
|
||||
|
@ -162,6 +172,24 @@ function f20(x: unknown) {
|
|||
const t2: Test = new Test();
|
||||
t2.assert(typeof x === "string");
|
||||
}
|
||||
|
||||
// Repro from #35940
|
||||
|
||||
interface Thing {
|
||||
good: boolean;
|
||||
isGood(): asserts this is GoodThing;
|
||||
}
|
||||
|
||||
interface GoodThing {
|
||||
good: true;
|
||||
}
|
||||
|
||||
function example1(things: Thing[]) {
|
||||
for (let thing of things) {
|
||||
thing.isGood();
|
||||
thing.good;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [assertionTypePredicates1.js]
|
||||
|
@ -319,6 +347,16 @@ var Derived = /** @class */ (function (_super) {
|
|||
};
|
||||
return Derived;
|
||||
}(Test));
|
||||
function f11(items) {
|
||||
for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
|
||||
var item = items_1[_i];
|
||||
if (item.isTest2()) {
|
||||
item.z;
|
||||
}
|
||||
item.assertIsTest2();
|
||||
item.z;
|
||||
}
|
||||
}
|
||||
function f20(x) {
|
||||
var assert = function (value) { };
|
||||
assert(typeof x === "string"); // Error
|
||||
|
@ -329,6 +367,13 @@ function f20(x) {
|
|||
var t2 = new Test();
|
||||
t2.assert(typeof x === "string");
|
||||
}
|
||||
function example1(things) {
|
||||
for (var _i = 0, things_1 = things; _i < things_1.length; _i++) {
|
||||
var thing = things_1[_i];
|
||||
thing.isGood();
|
||||
thing.good;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [assertionTypePredicates1.d.ts]
|
||||
|
@ -362,6 +407,7 @@ declare class Derived extends Test {
|
|||
foo(x: unknown): void;
|
||||
baz(x: number): void;
|
||||
}
|
||||
declare function f11(items: Test[]): 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;
|
||||
|
@ -372,3 +418,11 @@ declare class Wat {
|
|||
set p2(x: asserts this is string);
|
||||
}
|
||||
declare function f20(x: unknown): void;
|
||||
interface Thing {
|
||||
good: boolean;
|
||||
isGood(): asserts this is GoodThing;
|
||||
}
|
||||
interface GoodThing {
|
||||
good: true;
|
||||
}
|
||||
declare function example1(things: Thing[]): void;
|
||||
|
|
|
@ -392,81 +392,153 @@ class Derived extends Test {
|
|||
}
|
||||
}
|
||||
|
||||
function f11(items: Test[]) {
|
||||
>f11 : Symbol(f11, Decl(assertionTypePredicates1.ts, 138, 1))
|
||||
>items : Symbol(items, Decl(assertionTypePredicates1.ts, 140, 13))
|
||||
>Test : Symbol(Test, Decl(assertionTypePredicates1.ts, 88, 1))
|
||||
|
||||
for (let item of items) {
|
||||
>item : Symbol(item, Decl(assertionTypePredicates1.ts, 141, 12))
|
||||
>items : Symbol(items, Decl(assertionTypePredicates1.ts, 140, 13))
|
||||
|
||||
if (item.isTest2()) {
|
||||
>item.isTest2 : Symbol(Test.isTest2, Decl(assertionTypePredicates1.ts, 94, 5))
|
||||
>item : Symbol(item, Decl(assertionTypePredicates1.ts, 141, 12))
|
||||
>isTest2 : Symbol(Test.isTest2, Decl(assertionTypePredicates1.ts, 94, 5))
|
||||
|
||||
item.z;
|
||||
>item.z : Symbol(Test2.z, Decl(assertionTypePredicates1.ts, 125, 26))
|
||||
>item : Symbol(item, Decl(assertionTypePredicates1.ts, 141, 12))
|
||||
>z : Symbol(Test2.z, Decl(assertionTypePredicates1.ts, 125, 26))
|
||||
}
|
||||
item.assertIsTest2();
|
||||
>item.assertIsTest2 : Symbol(Test.assertIsTest2, Decl(assertionTypePredicates1.ts, 97, 5))
|
||||
>item : Symbol(item, Decl(assertionTypePredicates1.ts, 141, 12))
|
||||
>assertIsTest2 : Symbol(Test.assertIsTest2, Decl(assertionTypePredicates1.ts, 97, 5))
|
||||
|
||||
item.z;
|
||||
>item.z : Symbol(Test2.z, Decl(assertionTypePredicates1.ts, 125, 26))
|
||||
>item : Symbol(item, Decl(assertionTypePredicates1.ts, 141, 12))
|
||||
>z : Symbol(Test2.z, Decl(assertionTypePredicates1.ts, 125, 26))
|
||||
}
|
||||
}
|
||||
|
||||
// Invalid constructs
|
||||
|
||||
declare let Q1: new (x: unknown) => x is string;
|
||||
>Q1 : Symbol(Q1, Decl(assertionTypePredicates1.ts, 142, 11))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 142, 21))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 142, 21))
|
||||
>Q1 : Symbol(Q1, Decl(assertionTypePredicates1.ts, 152, 11))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 152, 21))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 152, 21))
|
||||
|
||||
declare let Q2: new (x: boolean) => asserts x;
|
||||
>Q2 : Symbol(Q2, Decl(assertionTypePredicates1.ts, 143, 11))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 143, 21))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 143, 21))
|
||||
>Q2 : Symbol(Q2, Decl(assertionTypePredicates1.ts, 153, 11))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 153, 21))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 153, 21))
|
||||
|
||||
declare let Q3: new (x: unknown) => asserts x is string;
|
||||
>Q3 : Symbol(Q3, Decl(assertionTypePredicates1.ts, 144, 11))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 144, 21))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 144, 21))
|
||||
>Q3 : Symbol(Q3, Decl(assertionTypePredicates1.ts, 154, 11))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 154, 21))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 154, 21))
|
||||
|
||||
declare class Wat {
|
||||
>Wat : Symbol(Wat, Decl(assertionTypePredicates1.ts, 144, 56))
|
||||
>Wat : Symbol(Wat, Decl(assertionTypePredicates1.ts, 154, 56))
|
||||
|
||||
get p1(): this is string;
|
||||
>p1 : Symbol(Wat.p1, Decl(assertionTypePredicates1.ts, 146, 19), Decl(assertionTypePredicates1.ts, 147, 29))
|
||||
>p1 : Symbol(Wat.p1, Decl(assertionTypePredicates1.ts, 156, 19), Decl(assertionTypePredicates1.ts, 157, 29))
|
||||
|
||||
set p1(x: this is string);
|
||||
>p1 : Symbol(Wat.p1, Decl(assertionTypePredicates1.ts, 146, 19), Decl(assertionTypePredicates1.ts, 147, 29))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 148, 11))
|
||||
>p1 : Symbol(Wat.p1, Decl(assertionTypePredicates1.ts, 156, 19), Decl(assertionTypePredicates1.ts, 157, 29))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 158, 11))
|
||||
|
||||
get p2(): asserts this is string;
|
||||
>p2 : Symbol(Wat.p2, Decl(assertionTypePredicates1.ts, 148, 30), Decl(assertionTypePredicates1.ts, 149, 37))
|
||||
>p2 : Symbol(Wat.p2, Decl(assertionTypePredicates1.ts, 158, 30), Decl(assertionTypePredicates1.ts, 159, 37))
|
||||
|
||||
set p2(x: asserts this is string);
|
||||
>p2 : Symbol(Wat.p2, Decl(assertionTypePredicates1.ts, 148, 30), Decl(assertionTypePredicates1.ts, 149, 37))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 150, 11))
|
||||
>p2 : Symbol(Wat.p2, Decl(assertionTypePredicates1.ts, 158, 30), Decl(assertionTypePredicates1.ts, 159, 37))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 160, 11))
|
||||
}
|
||||
|
||||
function f20(x: unknown) {
|
||||
>f20 : Symbol(f20, Decl(assertionTypePredicates1.ts, 151, 1))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 153, 13))
|
||||
>f20 : Symbol(f20, Decl(assertionTypePredicates1.ts, 161, 1))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 163, 13))
|
||||
|
||||
const assert = (value: unknown): asserts value => {}
|
||||
>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 : Symbol(assert, Decl(assertionTypePredicates1.ts, 164, 9))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 164, 20))
|
||||
>value : Symbol(value, Decl(assertionTypePredicates1.ts, 164, 20))
|
||||
|
||||
assert(typeof x === "string"); // Error
|
||||
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 154, 9))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 153, 13))
|
||||
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 164, 9))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 163, 13))
|
||||
|
||||
const a = [assert];
|
||||
>a : Symbol(a, Decl(assertionTypePredicates1.ts, 156, 9))
|
||||
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 154, 9))
|
||||
>a : Symbol(a, Decl(assertionTypePredicates1.ts, 166, 9))
|
||||
>assert : Symbol(assert, Decl(assertionTypePredicates1.ts, 164, 9))
|
||||
|
||||
a[0](typeof x === "string"); // Error
|
||||
>a : Symbol(a, Decl(assertionTypePredicates1.ts, 156, 9))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 153, 13))
|
||||
>a : Symbol(a, Decl(assertionTypePredicates1.ts, 166, 9))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 163, 13))
|
||||
|
||||
const t1 = new Test();
|
||||
>t1 : Symbol(t1, Decl(assertionTypePredicates1.ts, 158, 9))
|
||||
>t1 : Symbol(t1, Decl(assertionTypePredicates1.ts, 168, 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, 158, 9))
|
||||
>t1 : Symbol(t1, Decl(assertionTypePredicates1.ts, 168, 9))
|
||||
>assert : Symbol(Test.assert, Decl(assertionTypePredicates1.ts, 90, 12))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 153, 13))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 163, 13))
|
||||
|
||||
const t2: Test = new Test();
|
||||
>t2 : Symbol(t2, Decl(assertionTypePredicates1.ts, 160, 9))
|
||||
>t2 : Symbol(t2, Decl(assertionTypePredicates1.ts, 170, 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, 160, 9))
|
||||
>t2 : Symbol(t2, Decl(assertionTypePredicates1.ts, 170, 9))
|
||||
>assert : Symbol(Test.assert, Decl(assertionTypePredicates1.ts, 90, 12))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 153, 13))
|
||||
>x : Symbol(x, Decl(assertionTypePredicates1.ts, 163, 13))
|
||||
}
|
||||
|
||||
// Repro from #35940
|
||||
|
||||
interface Thing {
|
||||
>Thing : Symbol(Thing, Decl(assertionTypePredicates1.ts, 172, 1))
|
||||
|
||||
good: boolean;
|
||||
>good : Symbol(Thing.good, Decl(assertionTypePredicates1.ts, 176, 17))
|
||||
|
||||
isGood(): asserts this is GoodThing;
|
||||
>isGood : Symbol(Thing.isGood, Decl(assertionTypePredicates1.ts, 177, 18))
|
||||
>GoodThing : Symbol(GoodThing, Decl(assertionTypePredicates1.ts, 179, 1))
|
||||
}
|
||||
|
||||
interface GoodThing {
|
||||
>GoodThing : Symbol(GoodThing, Decl(assertionTypePredicates1.ts, 179, 1))
|
||||
|
||||
good: true;
|
||||
>good : Symbol(GoodThing.good, Decl(assertionTypePredicates1.ts, 181, 21))
|
||||
}
|
||||
|
||||
function example1(things: Thing[]) {
|
||||
>example1 : Symbol(example1, Decl(assertionTypePredicates1.ts, 183, 1))
|
||||
>things : Symbol(things, Decl(assertionTypePredicates1.ts, 185, 18))
|
||||
>Thing : Symbol(Thing, Decl(assertionTypePredicates1.ts, 172, 1))
|
||||
|
||||
for (let thing of things) {
|
||||
>thing : Symbol(thing, Decl(assertionTypePredicates1.ts, 186, 12))
|
||||
>things : Symbol(things, Decl(assertionTypePredicates1.ts, 185, 18))
|
||||
|
||||
thing.isGood();
|
||||
>thing.isGood : Symbol(Thing.isGood, Decl(assertionTypePredicates1.ts, 177, 18))
|
||||
>thing : Symbol(thing, Decl(assertionTypePredicates1.ts, 186, 12))
|
||||
>isGood : Symbol(Thing.isGood, Decl(assertionTypePredicates1.ts, 177, 18))
|
||||
|
||||
thing.good;
|
||||
>thing.good : Symbol(good, Decl(assertionTypePredicates1.ts, 176, 17), Decl(assertionTypePredicates1.ts, 181, 21))
|
||||
>thing : Symbol(thing, Decl(assertionTypePredicates1.ts, 186, 12))
|
||||
>good : Symbol(good, Decl(assertionTypePredicates1.ts, 176, 17), Decl(assertionTypePredicates1.ts, 181, 21))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -502,6 +502,38 @@ class Derived extends Test {
|
|||
}
|
||||
}
|
||||
|
||||
function f11(items: Test[]) {
|
||||
>f11 : (items: Test[]) => void
|
||||
>items : Test[]
|
||||
|
||||
for (let item of items) {
|
||||
>item : Test
|
||||
>items : Test[]
|
||||
|
||||
if (item.isTest2()) {
|
||||
>item.isTest2() : boolean
|
||||
>item.isTest2 : () => this is Test2
|
||||
>item : Test
|
||||
>isTest2 : () => this is Test2
|
||||
|
||||
item.z;
|
||||
>item.z : number
|
||||
>item : Test2
|
||||
>z : number
|
||||
}
|
||||
item.assertIsTest2();
|
||||
>item.assertIsTest2() : void
|
||||
>item.assertIsTest2 : () => asserts this is Test2
|
||||
>item : Test
|
||||
>assertIsTest2 : () => asserts this is Test2
|
||||
|
||||
item.z;
|
||||
>item.z : number
|
||||
>item : Test2
|
||||
>z : number
|
||||
}
|
||||
}
|
||||
|
||||
// Invalid constructs
|
||||
|
||||
declare let Q1: new (x: unknown) => x is string;
|
||||
|
@ -597,3 +629,40 @@ function f20(x: unknown) {
|
|||
>"string" : "string"
|
||||
}
|
||||
|
||||
// Repro from #35940
|
||||
|
||||
interface Thing {
|
||||
good: boolean;
|
||||
>good : boolean
|
||||
|
||||
isGood(): asserts this is GoodThing;
|
||||
>isGood : () => asserts this is GoodThing
|
||||
}
|
||||
|
||||
interface GoodThing {
|
||||
good: true;
|
||||
>good : true
|
||||
>true : true
|
||||
}
|
||||
|
||||
function example1(things: Thing[]) {
|
||||
>example1 : (things: Thing[]) => void
|
||||
>things : Thing[]
|
||||
|
||||
for (let thing of things) {
|
||||
>thing : Thing
|
||||
>things : Thing[]
|
||||
|
||||
thing.isGood();
|
||||
>thing.isGood() : void
|
||||
>thing.isGood : () => asserts this is GoodThing
|
||||
>thing : Thing
|
||||
>isGood : () => asserts this is GoodThing
|
||||
|
||||
thing.good;
|
||||
>thing.good : true
|
||||
>thing : Thing & GoodThing
|
||||
>good : true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -142,6 +142,16 @@ class Derived extends Test {
|
|||
}
|
||||
}
|
||||
|
||||
function f11(items: Test[]) {
|
||||
for (let item of items) {
|
||||
if (item.isTest2()) {
|
||||
item.z;
|
||||
}
|
||||
item.assertIsTest2();
|
||||
item.z;
|
||||
}
|
||||
}
|
||||
|
||||
// Invalid constructs
|
||||
|
||||
declare let Q1: new (x: unknown) => x is string;
|
||||
|
@ -165,3 +175,21 @@ function f20(x: unknown) {
|
|||
const t2: Test = new Test();
|
||||
t2.assert(typeof x === "string");
|
||||
}
|
||||
|
||||
// Repro from #35940
|
||||
|
||||
interface Thing {
|
||||
good: boolean;
|
||||
isGood(): asserts this is GoodThing;
|
||||
}
|
||||
|
||||
interface GoodThing {
|
||||
good: true;
|
||||
}
|
||||
|
||||
function example1(things: Thing[]) {
|
||||
for (let thing of things) {
|
||||
thing.isGood();
|
||||
thing.good;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue