mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into builderApi
This commit is contained in:
@@ -749,6 +749,10 @@ namespace ts {
|
||||
return expr1.kind === SyntaxKind.TypeOfExpression && isNarrowableOperand((<TypeOfExpression>expr1).expression) && expr2.kind === SyntaxKind.StringLiteral;
|
||||
}
|
||||
|
||||
function isNarrowableInOperands(left: Expression, right: Expression) {
|
||||
return left.kind === SyntaxKind.StringLiteral && isNarrowingExpression(right);
|
||||
}
|
||||
|
||||
function isNarrowingBinaryExpression(expr: BinaryExpression) {
|
||||
switch (expr.operatorToken.kind) {
|
||||
case SyntaxKind.EqualsToken:
|
||||
@@ -761,6 +765,8 @@ namespace ts {
|
||||
isNarrowingTypeofOperands(expr.right, expr.left) || isNarrowingTypeofOperands(expr.left, expr.right);
|
||||
case SyntaxKind.InstanceOfKeyword:
|
||||
return isNarrowableOperand(expr.left);
|
||||
case SyntaxKind.InKeyword:
|
||||
return isNarrowableInOperands(expr.left, expr.right);
|
||||
case SyntaxKind.CommaToken:
|
||||
return isNarrowingExpression(expr.right);
|
||||
}
|
||||
|
||||
+28
-6
@@ -1022,7 +1022,7 @@ namespace ts {
|
||||
|
||||
// It's an external module. First see if the module has an export default and if the local
|
||||
// name of that export default matches.
|
||||
if (result = moduleExports.get("default" as __String)) {
|
||||
if (result = moduleExports.get(InternalSymbolName.Default)) {
|
||||
const localSymbol = getLocalSymbolForExportDefault(result);
|
||||
if (localSymbol && (result.flags & meaning) && localSymbol.escapedName === name) {
|
||||
break loop;
|
||||
@@ -1476,8 +1476,8 @@ namespace ts {
|
||||
else {
|
||||
const exportValue = moduleSymbol.exports.get("export=" as __String);
|
||||
exportDefaultSymbol = exportValue
|
||||
? getPropertyOfType(getTypeOfSymbol(exportValue), "default" as __String)
|
||||
: resolveSymbol(moduleSymbol.exports.get("default" as __String), dontResolveAlias);
|
||||
? getPropertyOfType(getTypeOfSymbol(exportValue), InternalSymbolName.Default)
|
||||
: resolveSymbol(moduleSymbol.exports.get(InternalSymbolName.Default), dontResolveAlias);
|
||||
}
|
||||
|
||||
if (!exportDefaultSymbol && !allowSyntheticDefaultImports) {
|
||||
@@ -1566,7 +1566,7 @@ namespace ts {
|
||||
symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias);
|
||||
let symbolFromModule = getExportOfModule(targetSymbol, name.escapedText, dontResolveAlias);
|
||||
// If the export member we're looking for is default, and there is no real default but allowSyntheticDefaultImports is on, return the entire module as the default
|
||||
if (!symbolFromModule && allowSyntheticDefaultImports && name.escapedText === "default") {
|
||||
if (!symbolFromModule && allowSyntheticDefaultImports && name.escapedText === InternalSymbolName.Default) {
|
||||
symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
|
||||
}
|
||||
const symbol = symbolFromModule && symbolFromVariable ?
|
||||
@@ -1953,7 +1953,7 @@ namespace ts {
|
||||
function extendExportSymbols(target: SymbolTable, source: SymbolTable | undefined, lookupTable?: ExportCollisionTrackerTable, exportNode?: ExportDeclaration) {
|
||||
if (!source) return;
|
||||
source.forEach((sourceSymbol, id) => {
|
||||
if (id === "default") return;
|
||||
if (id === InternalSymbolName.Default) return;
|
||||
|
||||
const targetSymbol = target.get(id);
|
||||
if (!targetSymbol) {
|
||||
@@ -3223,7 +3223,7 @@ namespace ts {
|
||||
* ensuring that any names written with literals use element accesses.
|
||||
*/
|
||||
function appendPropertyOrElementAccessForSymbol(symbol: Symbol, writer: SymbolWriter): void {
|
||||
const symbolName = symbol.escapedName === "default" ? "default" : getNameOfSymbolAsWritten(symbol);
|
||||
const symbolName = symbol.escapedName === InternalSymbolName.Default ? InternalSymbolName.Default : getNameOfSymbolAsWritten(symbol);
|
||||
const firstChar = symbolName.charCodeAt(0);
|
||||
const needsElementAccess = !isIdentifierStart(firstChar, languageVersion);
|
||||
|
||||
@@ -12724,6 +12724,22 @@ namespace ts {
|
||||
return type;
|
||||
}
|
||||
|
||||
function isTypePresencePossible(type: Type, propName: __String, assumeTrue: boolean) {
|
||||
const prop = getPropertyOfType(type, propName);
|
||||
if (prop) {
|
||||
return (prop.flags & SymbolFlags.Optional) ? true : assumeTrue;
|
||||
}
|
||||
return !assumeTrue;
|
||||
}
|
||||
|
||||
function narrowByInKeyword(type: Type, literal: LiteralExpression, assumeTrue: boolean) {
|
||||
if ((type.flags & (TypeFlags.Union | TypeFlags.Object)) || (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType)) {
|
||||
const propName = escapeLeadingUnderscores(literal.text);
|
||||
return filterType(type, t => isTypePresencePossible(t, propName, /* assumeTrue */ assumeTrue));
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function narrowTypeByBinaryExpression(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
|
||||
switch (expr.operatorToken.kind) {
|
||||
case SyntaxKind.EqualsToken:
|
||||
@@ -12759,6 +12775,12 @@ namespace ts {
|
||||
break;
|
||||
case SyntaxKind.InstanceOfKeyword:
|
||||
return narrowTypeByInstanceof(type, expr, assumeTrue);
|
||||
case SyntaxKind.InKeyword:
|
||||
const target = getReferenceCandidate(expr.right);
|
||||
if (expr.left.kind === SyntaxKind.StringLiteral && isMatchingReference(reference, target)) {
|
||||
return narrowByInKeyword(type, <LiteralExpression>expr.left, assumeTrue);
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.CommaToken:
|
||||
return narrowType(type, expr.right, assumeTrue);
|
||||
}
|
||||
|
||||
@@ -1571,15 +1571,15 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
private applyCodeActionCommand(commandName: string, requestSeq: number, args: protocol.ApplyCodeActionCommandRequestArgs): void {
|
||||
private applyCodeActionCommand(args: protocol.ApplyCodeActionCommandRequestArgs): {} {
|
||||
const commands = args.command as CodeActionCommand | CodeActionCommand[]; // They should be sending back the command we sent them.
|
||||
for (const command of toArray(commands)) {
|
||||
const { project } = this.getFileAndProject(command);
|
||||
const output = (success: boolean, message: string) => this.doOutput({}, commandName, requestSeq, success, message);
|
||||
project.getLanguageService().applyCodeActionCommand(command).then(
|
||||
result => { output(/*success*/ true, result.successMessage); },
|
||||
error => { output(/*success*/ false, error); });
|
||||
_result => { /* TODO: GH#20447 report success message? */ },
|
||||
_error => { /* TODO: GH#20447 report errors */ });
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
private getStartAndEndPosition(args: protocol.FileRangeRequestArgs, scriptInfo: ScriptInfo) {
|
||||
@@ -1705,17 +1705,17 @@ namespace ts.server {
|
||||
private handlers = createMapFromTemplate<(request: protocol.Request) => HandlerResponse>({
|
||||
[CommandNames.OpenExternalProject]: (request: protocol.OpenExternalProjectRequest) => {
|
||||
this.projectService.openExternalProject(request.arguments, /*suppressRefreshOfInferredProjects*/ false);
|
||||
// TODO: report errors
|
||||
// TODO: GH#20447 report errors
|
||||
return this.requiredResponse(/*response*/ true);
|
||||
},
|
||||
[CommandNames.OpenExternalProjects]: (request: protocol.OpenExternalProjectsRequest) => {
|
||||
this.projectService.openExternalProjects(request.arguments.projects);
|
||||
// TODO: report errors
|
||||
// TODO: GH#20447 report errors
|
||||
return this.requiredResponse(/*response*/ true);
|
||||
},
|
||||
[CommandNames.CloseExternalProject]: (request: protocol.CloseExternalProjectRequest) => {
|
||||
this.projectService.closeExternalProject(request.arguments.projectFileName);
|
||||
// TODO: report errors
|
||||
// TODO: GH#20447 report errors
|
||||
return this.requiredResponse(/*response*/ true);
|
||||
},
|
||||
[CommandNames.SynchronizeProjectList]: (request: protocol.SynchronizeProjectListRequest) => {
|
||||
@@ -1957,8 +1957,7 @@ namespace ts.server {
|
||||
return this.requiredResponse(this.getCodeFixes(request.arguments, /*simplifiedResult*/ false));
|
||||
},
|
||||
[CommandNames.ApplyCodeActionCommand]: (request: protocol.ApplyCodeActionCommandRequest) => {
|
||||
this.applyCodeActionCommand(request.command, request.seq, request.arguments);
|
||||
return this.notRequired(); // Response will come asynchronously.
|
||||
return this.requiredResponse(this.applyCodeActionCommand(request.arguments));
|
||||
},
|
||||
[CommandNames.GetSupportedCodeFixes]: () => {
|
||||
return this.requiredResponse(this.getSupportedCodeFixes());
|
||||
|
||||
@@ -746,7 +746,7 @@ namespace ts.codefix {
|
||||
forEachExternalModuleToImportFrom(checker, sourceFile, allSourceFiles, moduleSymbol => {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
// check the default export
|
||||
const defaultExport = checker.tryGetMemberInModuleExports("default", moduleSymbol);
|
||||
const defaultExport = checker.tryGetMemberInModuleExports(InternalSymbolName.Default, moduleSymbol);
|
||||
if (defaultExport) {
|
||||
const localSymbol = getLocalSymbolForExportDefault(defaultExport);
|
||||
if ((localSymbol && localSymbol.escapedName === symbolName || moduleSymbolToValidIdentifier(moduleSymbol, context.compilerOptions.target) === symbolName)
|
||||
|
||||
@@ -39,6 +39,12 @@ namespace ts.Completions {
|
||||
return getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log);
|
||||
}
|
||||
|
||||
const contextToken = findPrecedingToken(position, sourceFile);
|
||||
if (contextToken && isBreakOrContinueStatement(contextToken.parent)
|
||||
&& (contextToken.kind === SyntaxKind.BreakKeyword || contextToken.kind === SyntaxKind.ContinueKeyword || contextToken.kind === SyntaxKind.Identifier)) {
|
||||
return getLabelCompletionAtPosition(contextToken.parent);
|
||||
}
|
||||
|
||||
const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, options, compilerOptions.target);
|
||||
if (!completionData) {
|
||||
return undefined;
|
||||
@@ -223,6 +229,13 @@ namespace ts.Completions {
|
||||
return uniques;
|
||||
}
|
||||
|
||||
function getLabelCompletionAtPosition(node: BreakOrContinueStatement): CompletionInfo | undefined {
|
||||
const entries = getLabelStatementCompletions(node);
|
||||
if (entries.length) {
|
||||
return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries };
|
||||
}
|
||||
}
|
||||
|
||||
function getStringLiteralCompletionEntries(sourceFile: SourceFile, position: number, typeChecker: TypeChecker, compilerOptions: CompilerOptions, host: LanguageServiceHost, log: Log): CompletionInfo | undefined {
|
||||
const node = findPrecedingToken(position, sourceFile);
|
||||
if (!node || node.kind !== SyntaxKind.StringLiteral) {
|
||||
@@ -358,6 +371,32 @@ namespace ts.Completions {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getLabelStatementCompletions(node: Node): CompletionEntry[] {
|
||||
const entries: CompletionEntry[] = [];
|
||||
const uniques = createMap<true>();
|
||||
let current = node;
|
||||
|
||||
while (current) {
|
||||
if (isFunctionLike(current)) {
|
||||
break;
|
||||
}
|
||||
if (isLabeledStatement(current)) {
|
||||
const name = current.label.text;
|
||||
if (!uniques.has(name)) {
|
||||
uniques.set(name, true);
|
||||
entries.push({
|
||||
name,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
kind: ScriptElementKind.label,
|
||||
sortText: "0"
|
||||
});
|
||||
}
|
||||
}
|
||||
current = current.parent;
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
function addStringLiteralCompletionsFromType(type: Type, result: Push<CompletionEntry>, typeChecker: TypeChecker, uniques = createMap<true>()): void {
|
||||
if (type && type.flags & TypeFlags.TypeParameter) {
|
||||
type = typeChecker.getBaseConstraintOfType(type);
|
||||
@@ -416,7 +455,9 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
function getSymbolName(symbol: Symbol, origin: SymbolOriginInfo | undefined, target: ScriptTarget): string {
|
||||
return origin && origin.isDefaultExport && symbol.name === "default" ? codefix.moduleSymbolToValidIdentifier(origin.moduleSymbol, target) : symbol.name;
|
||||
return origin && origin.isDefaultExport && symbol.escapedName === InternalSymbolName.Default
|
||||
? codefix.moduleSymbolToValidIdentifier(origin.moduleSymbol, target)
|
||||
: symbol.name;
|
||||
}
|
||||
|
||||
export interface CompletionEntryIdentifier {
|
||||
@@ -1076,7 +1117,7 @@ namespace ts.Completions {
|
||||
continue;
|
||||
}
|
||||
|
||||
const isDefaultExport = name === "default";
|
||||
const isDefaultExport = name === InternalSymbolName.Default;
|
||||
if (isDefaultExport) {
|
||||
const localSymbol = getLocalSymbolForExportDefault(symbol);
|
||||
if (localSymbol) {
|
||||
@@ -1756,10 +1797,10 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
if (existingImportsOrExports.size === 0) {
|
||||
return filter(exportsOfModule, e => e.escapedName !== "default");
|
||||
return filter(exportsOfModule, e => e.escapedName !== InternalSymbolName.Default);
|
||||
}
|
||||
|
||||
return filter(exportsOfModule, e => e.escapedName !== "default" && !existingImportsOrExports.get(e.escapedName));
|
||||
return filter(exportsOfModule, e => e.escapedName !== InternalSymbolName.Default && !existingImportsOrExports.get(e.escapedName));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -290,7 +290,7 @@ namespace ts.FindAllReferences {
|
||||
|
||||
function isNameMatch(name: __String): boolean {
|
||||
// Use name of "default" even in `export =` case because we may have allowSyntheticDefaultImports
|
||||
return name === exportSymbol.escapedName || exportKind !== ExportKind.Named && name === "default";
|
||||
return name === exportSymbol.escapedName || exportKind !== ExportKind.Named && name === InternalSymbolName.Default;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -534,7 +534,7 @@ namespace ts.FindAllReferences {
|
||||
// If `importedName` is undefined, do continue searching as the export is anonymous.
|
||||
// (All imports returned from this function will be ignored anyway if we are in rename and this is a not a named export.)
|
||||
const importedName = symbolName(importedSymbol);
|
||||
if (importedName === undefined || importedName === "default" || importedName === symbol.escapedName) {
|
||||
if (importedName === undefined || importedName === InternalSymbolName.Default || importedName === symbol.escapedName) {
|
||||
return { kind: ImportExport.Import, symbol: importedSymbol, ...isImport };
|
||||
}
|
||||
}
|
||||
@@ -604,7 +604,7 @@ namespace ts.FindAllReferences {
|
||||
}
|
||||
|
||||
function symbolName(symbol: Symbol): __String | undefined {
|
||||
if (symbol.escapedName !== "default") {
|
||||
if (symbol.escapedName !== InternalSymbolName.Default) {
|
||||
return symbol.escapedName;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -7138,7 +7138,7 @@ declare namespace ts.server {
|
||||
private getApplicableRefactors(args);
|
||||
private getEditsForRefactor(args, simplifiedResult);
|
||||
private getCodeFixes(args, simplifiedResult);
|
||||
private applyCodeActionCommand(commandName, requestSeq, args);
|
||||
private applyCodeActionCommand(args);
|
||||
private getStartAndEndPosition(args, scriptInfo);
|
||||
private mapCodeAction({description, changes: unmappedChanges, commands}, scriptInfo);
|
||||
private mapTextChangesToCodeEdits(project, textChanges);
|
||||
|
||||
@@ -3,6 +3,7 @@ tests/cases/conformance/fixSignatureCaching.ts(284,10): error TS2339: Property '
|
||||
tests/cases/conformance/fixSignatureCaching.ts(293,10): error TS2339: Property 'FALLBACK_PHONE' does not exist on type '{}'.
|
||||
tests/cases/conformance/fixSignatureCaching.ts(294,10): error TS2339: Property 'FALLBACK_TABLET' does not exist on type '{}'.
|
||||
tests/cases/conformance/fixSignatureCaching.ts(295,10): error TS2339: Property 'FALLBACK_MOBILE' does not exist on type '{}'.
|
||||
tests/cases/conformance/fixSignatureCaching.ts(301,17): error TS2339: Property 'isArray' does not exist on type 'never'.
|
||||
tests/cases/conformance/fixSignatureCaching.ts(330,74): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
|
||||
tests/cases/conformance/fixSignatureCaching.ts(369,10): error TS2339: Property 'findMatch' does not exist on type '{}'.
|
||||
tests/cases/conformance/fixSignatureCaching.ts(387,10): error TS2339: Property 'findMatches' does not exist on type '{}'.
|
||||
@@ -71,7 +72,7 @@ tests/cases/conformance/fixSignatureCaching.ts(982,23): error TS2304: Cannot fin
|
||||
tests/cases/conformance/fixSignatureCaching.ts(983,37): error TS2304: Cannot find name 'window'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/fixSignatureCaching.ts (71 errors) ====
|
||||
==== tests/cases/conformance/fixSignatureCaching.ts (72 errors) ====
|
||||
// Repro from #10697
|
||||
|
||||
(function (define, undefined) {
|
||||
@@ -383,6 +384,8 @@ tests/cases/conformance/fixSignatureCaching.ts(983,37): error TS2304: Cannot fin
|
||||
isArray = 'isArray' in Array
|
||||
? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; }
|
||||
: Array.isArray;
|
||||
~~~~~~~
|
||||
!!! error TS2339: Property 'isArray' does not exist on type 'never'.
|
||||
|
||||
function equalIC(a, b) {
|
||||
return a != null && b != null && a.toLowerCase() === b.toLowerCase();
|
||||
|
||||
@@ -358,9 +358,7 @@ define(function () {
|
||||
>value : Symbol(value, Decl(fixSignatureCaching.ts, 299, 20))
|
||||
|
||||
: Array.isArray;
|
||||
>Array.isArray : Symbol(ArrayConstructor.isArray, Decl(lib.d.ts, --, --))
|
||||
>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>isArray : Symbol(ArrayConstructor.isArray, Decl(lib.d.ts, --, --))
|
||||
|
||||
function equalIC(a, b) {
|
||||
>equalIC : Symbol(equalIC, Decl(fixSignatureCaching.ts, 300, 24))
|
||||
|
||||
@@ -893,9 +893,9 @@ define(function () {
|
||||
>'[object Array]' : "[object Array]"
|
||||
|
||||
isArray = 'isArray' in Array
|
||||
>isArray = 'isArray' in Array ? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; } : Array.isArray : (value: any) => boolean
|
||||
>isArray = 'isArray' in Array ? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; } : Array.isArray : any
|
||||
>isArray : any
|
||||
>'isArray' in Array ? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; } : Array.isArray : (value: any) => boolean
|
||||
>'isArray' in Array ? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; } : Array.isArray : any
|
||||
>'isArray' in Array : boolean
|
||||
>'isArray' : "isArray"
|
||||
>Array : ArrayConstructor
|
||||
@@ -916,9 +916,9 @@ define(function () {
|
||||
>'[object Array]' : "[object Array]"
|
||||
|
||||
: Array.isArray;
|
||||
>Array.isArray : (arg: any) => arg is any[]
|
||||
>Array : ArrayConstructor
|
||||
>isArray : (arg: any) => arg is any[]
|
||||
>Array.isArray : any
|
||||
>Array : never
|
||||
>isArray : any
|
||||
|
||||
function equalIC(a, b) {
|
||||
>equalIC : (a: any, b: any) => boolean
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
tests/cases/compiler/inKeywordTypeguard.ts(6,11): error TS2339: Property 'b' does not exist on type 'A'.
|
||||
tests/cases/compiler/inKeywordTypeguard.ts(8,11): error TS2339: Property 'a' does not exist on type 'B'.
|
||||
tests/cases/compiler/inKeywordTypeguard.ts(14,11): error TS2339: Property 'b' does not exist on type 'A'.
|
||||
tests/cases/compiler/inKeywordTypeguard.ts(16,11): error TS2339: Property 'a' does not exist on type 'B'.
|
||||
tests/cases/compiler/inKeywordTypeguard.ts(27,11): error TS2339: Property 'b' does not exist on type 'AWithOptionalProp | BWithOptionalProp'.
|
||||
Property 'b' does not exist on type 'AWithOptionalProp'.
|
||||
tests/cases/compiler/inKeywordTypeguard.ts(42,11): error TS2339: Property 'b' does not exist on type 'AWithMethod'.
|
||||
tests/cases/compiler/inKeywordTypeguard.ts(49,11): error TS2339: Property 'a' does not exist on type 'never'.
|
||||
tests/cases/compiler/inKeywordTypeguard.ts(50,11): error TS2339: Property 'b' does not exist on type 'never'.
|
||||
tests/cases/compiler/inKeywordTypeguard.ts(52,11): error TS2339: Property 'a' does not exist on type 'AWithMethod | BWithMethod'.
|
||||
Property 'a' does not exist on type 'BWithMethod'.
|
||||
tests/cases/compiler/inKeywordTypeguard.ts(53,11): error TS2339: Property 'b' does not exist on type 'AWithMethod | BWithMethod'.
|
||||
Property 'b' does not exist on type 'AWithMethod'.
|
||||
tests/cases/compiler/inKeywordTypeguard.ts(62,11): error TS2339: Property 'b' does not exist on type 'A | C | D'.
|
||||
Property 'b' does not exist on type 'A'.
|
||||
tests/cases/compiler/inKeywordTypeguard.ts(64,11): error TS2339: Property 'a' does not exist on type 'B'.
|
||||
tests/cases/compiler/inKeywordTypeguard.ts(72,32): error TS2339: Property 'b' does not exist on type 'A'.
|
||||
tests/cases/compiler/inKeywordTypeguard.ts(74,32): error TS2339: Property 'a' does not exist on type 'B'.
|
||||
tests/cases/compiler/inKeywordTypeguard.ts(82,39): error TS2339: Property 'b' does not exist on type 'A'.
|
||||
tests/cases/compiler/inKeywordTypeguard.ts(84,39): error TS2339: Property 'a' does not exist on type 'B'.
|
||||
tests/cases/compiler/inKeywordTypeguard.ts(94,26): error TS2339: Property 'a' does not exist on type 'never'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/inKeywordTypeguard.ts (17 errors) ====
|
||||
class A { a: string; }
|
||||
class B { b: string; }
|
||||
|
||||
function negativeClassesTest(x: A | B) {
|
||||
if ("a" in x) {
|
||||
x.b = "1";
|
||||
~
|
||||
!!! error TS2339: Property 'b' does not exist on type 'A'.
|
||||
} else {
|
||||
x.a = "1";
|
||||
~
|
||||
!!! error TS2339: Property 'a' does not exist on type 'B'.
|
||||
}
|
||||
}
|
||||
|
||||
function positiveClassesTest(x: A | B) {
|
||||
if ("a" in x) {
|
||||
x.b = "1";
|
||||
~
|
||||
!!! error TS2339: Property 'b' does not exist on type 'A'.
|
||||
} else {
|
||||
x.a = "1";
|
||||
~
|
||||
!!! error TS2339: Property 'a' does not exist on type 'B'.
|
||||
}
|
||||
}
|
||||
|
||||
class AWithOptionalProp { a?: string; }
|
||||
class BWithOptionalProp { b?: string; }
|
||||
|
||||
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
|
||||
if ("a" in x) {
|
||||
x.a = "1";
|
||||
} else {
|
||||
x.b = "1";
|
||||
~
|
||||
!!! error TS2339: Property 'b' does not exist on type 'AWithOptionalProp | BWithOptionalProp'.
|
||||
!!! error TS2339: Property 'b' does not exist on type 'AWithOptionalProp'.
|
||||
}
|
||||
}
|
||||
|
||||
class AWithMethod {
|
||||
a(): string { return ""; }
|
||||
}
|
||||
|
||||
class BWithMethod {
|
||||
b(): string { return ""; }
|
||||
}
|
||||
|
||||
function negativeTestClassesWithMembers(x: AWithMethod | BWithMethod) {
|
||||
if ("a" in x) {
|
||||
x.a();
|
||||
x.b();
|
||||
~
|
||||
!!! error TS2339: Property 'b' does not exist on type 'AWithMethod'.
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
function negativeTestClassesWithMemberMissingInBothClasses(x: AWithMethod | BWithMethod) {
|
||||
if ("c" in x) {
|
||||
x.a();
|
||||
~
|
||||
!!! error TS2339: Property 'a' does not exist on type 'never'.
|
||||
x.b();
|
||||
~
|
||||
!!! error TS2339: Property 'b' does not exist on type 'never'.
|
||||
} else {
|
||||
x.a();
|
||||
~
|
||||
!!! error TS2339: Property 'a' does not exist on type 'AWithMethod | BWithMethod'.
|
||||
!!! error TS2339: Property 'a' does not exist on type 'BWithMethod'.
|
||||
x.b();
|
||||
~
|
||||
!!! error TS2339: Property 'b' does not exist on type 'AWithMethod | BWithMethod'.
|
||||
!!! error TS2339: Property 'b' does not exist on type 'AWithMethod'.
|
||||
}
|
||||
}
|
||||
|
||||
class C { a: string; }
|
||||
class D { a: string; }
|
||||
|
||||
function negativeMultipleClassesTest(x: A | B | C | D) {
|
||||
if ("a" in x) {
|
||||
x.b = "1";
|
||||
~
|
||||
!!! error TS2339: Property 'b' does not exist on type 'A | C | D'.
|
||||
!!! error TS2339: Property 'b' does not exist on type 'A'.
|
||||
} else {
|
||||
x.a = "1";
|
||||
~
|
||||
!!! error TS2339: Property 'a' does not exist on type 'B'.
|
||||
}
|
||||
}
|
||||
|
||||
class ClassWithUnionProp { prop: A | B }
|
||||
|
||||
function negativePropTest(x: ClassWithUnionProp) {
|
||||
if ("a" in x.prop) {
|
||||
let y: string = x.prop.b;
|
||||
~
|
||||
!!! error TS2339: Property 'b' does not exist on type 'A'.
|
||||
} else {
|
||||
let z: string = x.prop.a;
|
||||
~
|
||||
!!! error TS2339: Property 'a' does not exist on type 'B'.
|
||||
}
|
||||
}
|
||||
|
||||
class NegativeClassTest {
|
||||
protected prop: A | B;
|
||||
inThis() {
|
||||
if ("a" in this.prop) {
|
||||
let z: number = this.prop.b;
|
||||
~
|
||||
!!! error TS2339: Property 'b' does not exist on type 'A'.
|
||||
} else {
|
||||
let y: string = this.prop.a;
|
||||
~
|
||||
!!! error TS2339: Property 'a' does not exist on type 'B'.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UnreachableCodeDetection {
|
||||
a: string;
|
||||
inThis() {
|
||||
if ("a" in this) {
|
||||
} else {
|
||||
let y = this.a;
|
||||
~
|
||||
!!! error TS2339: Property 'a' does not exist on type 'never'.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
//// [inKeywordTypeguard.ts]
|
||||
class A { a: string; }
|
||||
class B { b: string; }
|
||||
|
||||
function negativeClassesTest(x: A | B) {
|
||||
if ("a" in x) {
|
||||
x.b = "1";
|
||||
} else {
|
||||
x.a = "1";
|
||||
}
|
||||
}
|
||||
|
||||
function positiveClassesTest(x: A | B) {
|
||||
if ("a" in x) {
|
||||
x.b = "1";
|
||||
} else {
|
||||
x.a = "1";
|
||||
}
|
||||
}
|
||||
|
||||
class AWithOptionalProp { a?: string; }
|
||||
class BWithOptionalProp { b?: string; }
|
||||
|
||||
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
|
||||
if ("a" in x) {
|
||||
x.a = "1";
|
||||
} else {
|
||||
x.b = "1";
|
||||
}
|
||||
}
|
||||
|
||||
class AWithMethod {
|
||||
a(): string { return ""; }
|
||||
}
|
||||
|
||||
class BWithMethod {
|
||||
b(): string { return ""; }
|
||||
}
|
||||
|
||||
function negativeTestClassesWithMembers(x: AWithMethod | BWithMethod) {
|
||||
if ("a" in x) {
|
||||
x.a();
|
||||
x.b();
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
function negativeTestClassesWithMemberMissingInBothClasses(x: AWithMethod | BWithMethod) {
|
||||
if ("c" in x) {
|
||||
x.a();
|
||||
x.b();
|
||||
} else {
|
||||
x.a();
|
||||
x.b();
|
||||
}
|
||||
}
|
||||
|
||||
class C { a: string; }
|
||||
class D { a: string; }
|
||||
|
||||
function negativeMultipleClassesTest(x: A | B | C | D) {
|
||||
if ("a" in x) {
|
||||
x.b = "1";
|
||||
} else {
|
||||
x.a = "1";
|
||||
}
|
||||
}
|
||||
|
||||
class ClassWithUnionProp { prop: A | B }
|
||||
|
||||
function negativePropTest(x: ClassWithUnionProp) {
|
||||
if ("a" in x.prop) {
|
||||
let y: string = x.prop.b;
|
||||
} else {
|
||||
let z: string = x.prop.a;
|
||||
}
|
||||
}
|
||||
|
||||
class NegativeClassTest {
|
||||
protected prop: A | B;
|
||||
inThis() {
|
||||
if ("a" in this.prop) {
|
||||
let z: number = this.prop.b;
|
||||
} else {
|
||||
let y: string = this.prop.a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UnreachableCodeDetection {
|
||||
a: string;
|
||||
inThis() {
|
||||
if ("a" in this) {
|
||||
} else {
|
||||
let y = this.a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//// [inKeywordTypeguard.js]
|
||||
var A = /** @class */ (function () {
|
||||
function A() {
|
||||
}
|
||||
return A;
|
||||
}());
|
||||
var B = /** @class */ (function () {
|
||||
function B() {
|
||||
}
|
||||
return B;
|
||||
}());
|
||||
function negativeClassesTest(x) {
|
||||
if ("a" in x) {
|
||||
x.b = "1";
|
||||
}
|
||||
else {
|
||||
x.a = "1";
|
||||
}
|
||||
}
|
||||
function positiveClassesTest(x) {
|
||||
if ("a" in x) {
|
||||
x.b = "1";
|
||||
}
|
||||
else {
|
||||
x.a = "1";
|
||||
}
|
||||
}
|
||||
var AWithOptionalProp = /** @class */ (function () {
|
||||
function AWithOptionalProp() {
|
||||
}
|
||||
return AWithOptionalProp;
|
||||
}());
|
||||
var BWithOptionalProp = /** @class */ (function () {
|
||||
function BWithOptionalProp() {
|
||||
}
|
||||
return BWithOptionalProp;
|
||||
}());
|
||||
function positiveTestClassesWithOptionalProperties(x) {
|
||||
if ("a" in x) {
|
||||
x.a = "1";
|
||||
}
|
||||
else {
|
||||
x.b = "1";
|
||||
}
|
||||
}
|
||||
var AWithMethod = /** @class */ (function () {
|
||||
function AWithMethod() {
|
||||
}
|
||||
AWithMethod.prototype.a = function () { return ""; };
|
||||
return AWithMethod;
|
||||
}());
|
||||
var BWithMethod = /** @class */ (function () {
|
||||
function BWithMethod() {
|
||||
}
|
||||
BWithMethod.prototype.b = function () { return ""; };
|
||||
return BWithMethod;
|
||||
}());
|
||||
function negativeTestClassesWithMembers(x) {
|
||||
if ("a" in x) {
|
||||
x.a();
|
||||
x.b();
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
function negativeTestClassesWithMemberMissingInBothClasses(x) {
|
||||
if ("c" in x) {
|
||||
x.a();
|
||||
x.b();
|
||||
}
|
||||
else {
|
||||
x.a();
|
||||
x.b();
|
||||
}
|
||||
}
|
||||
var C = /** @class */ (function () {
|
||||
function C() {
|
||||
}
|
||||
return C;
|
||||
}());
|
||||
var D = /** @class */ (function () {
|
||||
function D() {
|
||||
}
|
||||
return D;
|
||||
}());
|
||||
function negativeMultipleClassesTest(x) {
|
||||
if ("a" in x) {
|
||||
x.b = "1";
|
||||
}
|
||||
else {
|
||||
x.a = "1";
|
||||
}
|
||||
}
|
||||
var ClassWithUnionProp = /** @class */ (function () {
|
||||
function ClassWithUnionProp() {
|
||||
}
|
||||
return ClassWithUnionProp;
|
||||
}());
|
||||
function negativePropTest(x) {
|
||||
if ("a" in x.prop) {
|
||||
var y = x.prop.b;
|
||||
}
|
||||
else {
|
||||
var z = x.prop.a;
|
||||
}
|
||||
}
|
||||
var NegativeClassTest = /** @class */ (function () {
|
||||
function NegativeClassTest() {
|
||||
}
|
||||
NegativeClassTest.prototype.inThis = function () {
|
||||
if ("a" in this.prop) {
|
||||
var z = this.prop.b;
|
||||
}
|
||||
else {
|
||||
var y = this.prop.a;
|
||||
}
|
||||
};
|
||||
return NegativeClassTest;
|
||||
}());
|
||||
var UnreachableCodeDetection = /** @class */ (function () {
|
||||
function UnreachableCodeDetection() {
|
||||
}
|
||||
UnreachableCodeDetection.prototype.inThis = function () {
|
||||
if ("a" in this) {
|
||||
}
|
||||
else {
|
||||
var y = this.a;
|
||||
}
|
||||
};
|
||||
return UnreachableCodeDetection;
|
||||
}());
|
||||
@@ -0,0 +1,241 @@
|
||||
=== tests/cases/compiler/inKeywordTypeguard.ts ===
|
||||
class A { a: string; }
|
||||
>A : Symbol(A, Decl(inKeywordTypeguard.ts, 0, 0))
|
||||
>a : Symbol(A.a, Decl(inKeywordTypeguard.ts, 0, 9))
|
||||
|
||||
class B { b: string; }
|
||||
>B : Symbol(B, Decl(inKeywordTypeguard.ts, 0, 22))
|
||||
>b : Symbol(B.b, Decl(inKeywordTypeguard.ts, 1, 9))
|
||||
|
||||
function negativeClassesTest(x: A | B) {
|
||||
>negativeClassesTest : Symbol(negativeClassesTest, Decl(inKeywordTypeguard.ts, 1, 22))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 3, 29))
|
||||
>A : Symbol(A, Decl(inKeywordTypeguard.ts, 0, 0))
|
||||
>B : Symbol(B, Decl(inKeywordTypeguard.ts, 0, 22))
|
||||
|
||||
if ("a" in x) {
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 3, 29))
|
||||
|
||||
x.b = "1";
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 3, 29))
|
||||
|
||||
} else {
|
||||
x.a = "1";
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 3, 29))
|
||||
}
|
||||
}
|
||||
|
||||
function positiveClassesTest(x: A | B) {
|
||||
>positiveClassesTest : Symbol(positiveClassesTest, Decl(inKeywordTypeguard.ts, 9, 1))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 11, 29))
|
||||
>A : Symbol(A, Decl(inKeywordTypeguard.ts, 0, 0))
|
||||
>B : Symbol(B, Decl(inKeywordTypeguard.ts, 0, 22))
|
||||
|
||||
if ("a" in x) {
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 11, 29))
|
||||
|
||||
x.b = "1";
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 11, 29))
|
||||
|
||||
} else {
|
||||
x.a = "1";
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 11, 29))
|
||||
}
|
||||
}
|
||||
|
||||
class AWithOptionalProp { a?: string; }
|
||||
>AWithOptionalProp : Symbol(AWithOptionalProp, Decl(inKeywordTypeguard.ts, 17, 1))
|
||||
>a : Symbol(AWithOptionalProp.a, Decl(inKeywordTypeguard.ts, 19, 25))
|
||||
|
||||
class BWithOptionalProp { b?: string; }
|
||||
>BWithOptionalProp : Symbol(BWithOptionalProp, Decl(inKeywordTypeguard.ts, 19, 39))
|
||||
>b : Symbol(BWithOptionalProp.b, Decl(inKeywordTypeguard.ts, 20, 25))
|
||||
|
||||
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
|
||||
>positiveTestClassesWithOptionalProperties : Symbol(positiveTestClassesWithOptionalProperties, Decl(inKeywordTypeguard.ts, 20, 39))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 22, 51))
|
||||
>AWithOptionalProp : Symbol(AWithOptionalProp, Decl(inKeywordTypeguard.ts, 17, 1))
|
||||
>BWithOptionalProp : Symbol(BWithOptionalProp, Decl(inKeywordTypeguard.ts, 19, 39))
|
||||
|
||||
if ("a" in x) {
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 22, 51))
|
||||
|
||||
x.a = "1";
|
||||
>x.a : Symbol(AWithOptionalProp.a, Decl(inKeywordTypeguard.ts, 19, 25))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 22, 51))
|
||||
>a : Symbol(AWithOptionalProp.a, Decl(inKeywordTypeguard.ts, 19, 25))
|
||||
|
||||
} else {
|
||||
x.b = "1";
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 22, 51))
|
||||
}
|
||||
}
|
||||
|
||||
class AWithMethod {
|
||||
>AWithMethod : Symbol(AWithMethod, Decl(inKeywordTypeguard.ts, 28, 1))
|
||||
|
||||
a(): string { return ""; }
|
||||
>a : Symbol(AWithMethod.a, Decl(inKeywordTypeguard.ts, 30, 19))
|
||||
}
|
||||
|
||||
class BWithMethod {
|
||||
>BWithMethod : Symbol(BWithMethod, Decl(inKeywordTypeguard.ts, 32, 1))
|
||||
|
||||
b(): string { return ""; }
|
||||
>b : Symbol(BWithMethod.b, Decl(inKeywordTypeguard.ts, 34, 19))
|
||||
}
|
||||
|
||||
function negativeTestClassesWithMembers(x: AWithMethod | BWithMethod) {
|
||||
>negativeTestClassesWithMembers : Symbol(negativeTestClassesWithMembers, Decl(inKeywordTypeguard.ts, 36, 1))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 38, 40))
|
||||
>AWithMethod : Symbol(AWithMethod, Decl(inKeywordTypeguard.ts, 28, 1))
|
||||
>BWithMethod : Symbol(BWithMethod, Decl(inKeywordTypeguard.ts, 32, 1))
|
||||
|
||||
if ("a" in x) {
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 38, 40))
|
||||
|
||||
x.a();
|
||||
>x.a : Symbol(AWithMethod.a, Decl(inKeywordTypeguard.ts, 30, 19))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 38, 40))
|
||||
>a : Symbol(AWithMethod.a, Decl(inKeywordTypeguard.ts, 30, 19))
|
||||
|
||||
x.b();
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 38, 40))
|
||||
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
function negativeTestClassesWithMemberMissingInBothClasses(x: AWithMethod | BWithMethod) {
|
||||
>negativeTestClassesWithMemberMissingInBothClasses : Symbol(negativeTestClassesWithMemberMissingInBothClasses, Decl(inKeywordTypeguard.ts, 44, 1))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 46, 59))
|
||||
>AWithMethod : Symbol(AWithMethod, Decl(inKeywordTypeguard.ts, 28, 1))
|
||||
>BWithMethod : Symbol(BWithMethod, Decl(inKeywordTypeguard.ts, 32, 1))
|
||||
|
||||
if ("c" in x) {
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 46, 59))
|
||||
|
||||
x.a();
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 46, 59))
|
||||
|
||||
x.b();
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 46, 59))
|
||||
|
||||
} else {
|
||||
x.a();
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 46, 59))
|
||||
|
||||
x.b();
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 46, 59))
|
||||
}
|
||||
}
|
||||
|
||||
class C { a: string; }
|
||||
>C : Symbol(C, Decl(inKeywordTypeguard.ts, 54, 1))
|
||||
>a : Symbol(C.a, Decl(inKeywordTypeguard.ts, 56, 9))
|
||||
|
||||
class D { a: string; }
|
||||
>D : Symbol(D, Decl(inKeywordTypeguard.ts, 56, 22))
|
||||
>a : Symbol(D.a, Decl(inKeywordTypeguard.ts, 57, 9))
|
||||
|
||||
function negativeMultipleClassesTest(x: A | B | C | D) {
|
||||
>negativeMultipleClassesTest : Symbol(negativeMultipleClassesTest, Decl(inKeywordTypeguard.ts, 57, 22))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 59, 37))
|
||||
>A : Symbol(A, Decl(inKeywordTypeguard.ts, 0, 0))
|
||||
>B : Symbol(B, Decl(inKeywordTypeguard.ts, 0, 22))
|
||||
>C : Symbol(C, Decl(inKeywordTypeguard.ts, 54, 1))
|
||||
>D : Symbol(D, Decl(inKeywordTypeguard.ts, 56, 22))
|
||||
|
||||
if ("a" in x) {
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 59, 37))
|
||||
|
||||
x.b = "1";
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 59, 37))
|
||||
|
||||
} else {
|
||||
x.a = "1";
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 59, 37))
|
||||
}
|
||||
}
|
||||
|
||||
class ClassWithUnionProp { prop: A | B }
|
||||
>ClassWithUnionProp : Symbol(ClassWithUnionProp, Decl(inKeywordTypeguard.ts, 65, 1))
|
||||
>prop : Symbol(ClassWithUnionProp.prop, Decl(inKeywordTypeguard.ts, 67, 26))
|
||||
>A : Symbol(A, Decl(inKeywordTypeguard.ts, 0, 0))
|
||||
>B : Symbol(B, Decl(inKeywordTypeguard.ts, 0, 22))
|
||||
|
||||
function negativePropTest(x: ClassWithUnionProp) {
|
||||
>negativePropTest : Symbol(negativePropTest, Decl(inKeywordTypeguard.ts, 67, 40))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 69, 26))
|
||||
>ClassWithUnionProp : Symbol(ClassWithUnionProp, Decl(inKeywordTypeguard.ts, 65, 1))
|
||||
|
||||
if ("a" in x.prop) {
|
||||
>x.prop : Symbol(ClassWithUnionProp.prop, Decl(inKeywordTypeguard.ts, 67, 26))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 69, 26))
|
||||
>prop : Symbol(ClassWithUnionProp.prop, Decl(inKeywordTypeguard.ts, 67, 26))
|
||||
|
||||
let y: string = x.prop.b;
|
||||
>y : Symbol(y, Decl(inKeywordTypeguard.ts, 71, 11))
|
||||
>x.prop : Symbol(ClassWithUnionProp.prop, Decl(inKeywordTypeguard.ts, 67, 26))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 69, 26))
|
||||
>prop : Symbol(ClassWithUnionProp.prop, Decl(inKeywordTypeguard.ts, 67, 26))
|
||||
|
||||
} else {
|
||||
let z: string = x.prop.a;
|
||||
>z : Symbol(z, Decl(inKeywordTypeguard.ts, 73, 11))
|
||||
>x.prop : Symbol(ClassWithUnionProp.prop, Decl(inKeywordTypeguard.ts, 67, 26))
|
||||
>x : Symbol(x, Decl(inKeywordTypeguard.ts, 69, 26))
|
||||
>prop : Symbol(ClassWithUnionProp.prop, Decl(inKeywordTypeguard.ts, 67, 26))
|
||||
}
|
||||
}
|
||||
|
||||
class NegativeClassTest {
|
||||
>NegativeClassTest : Symbol(NegativeClassTest, Decl(inKeywordTypeguard.ts, 75, 1))
|
||||
|
||||
protected prop: A | B;
|
||||
>prop : Symbol(NegativeClassTest.prop, Decl(inKeywordTypeguard.ts, 77, 25))
|
||||
>A : Symbol(A, Decl(inKeywordTypeguard.ts, 0, 0))
|
||||
>B : Symbol(B, Decl(inKeywordTypeguard.ts, 0, 22))
|
||||
|
||||
inThis() {
|
||||
>inThis : Symbol(NegativeClassTest.inThis, Decl(inKeywordTypeguard.ts, 78, 26))
|
||||
|
||||
if ("a" in this.prop) {
|
||||
>this.prop : Symbol(NegativeClassTest.prop, Decl(inKeywordTypeguard.ts, 77, 25))
|
||||
>this : Symbol(NegativeClassTest, Decl(inKeywordTypeguard.ts, 75, 1))
|
||||
>prop : Symbol(NegativeClassTest.prop, Decl(inKeywordTypeguard.ts, 77, 25))
|
||||
|
||||
let z: number = this.prop.b;
|
||||
>z : Symbol(z, Decl(inKeywordTypeguard.ts, 81, 15))
|
||||
>this.prop : Symbol(NegativeClassTest.prop, Decl(inKeywordTypeguard.ts, 77, 25))
|
||||
>this : Symbol(NegativeClassTest, Decl(inKeywordTypeguard.ts, 75, 1))
|
||||
>prop : Symbol(NegativeClassTest.prop, Decl(inKeywordTypeguard.ts, 77, 25))
|
||||
|
||||
} else {
|
||||
let y: string = this.prop.a;
|
||||
>y : Symbol(y, Decl(inKeywordTypeguard.ts, 83, 15))
|
||||
>this.prop : Symbol(NegativeClassTest.prop, Decl(inKeywordTypeguard.ts, 77, 25))
|
||||
>this : Symbol(NegativeClassTest, Decl(inKeywordTypeguard.ts, 75, 1))
|
||||
>prop : Symbol(NegativeClassTest.prop, Decl(inKeywordTypeguard.ts, 77, 25))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UnreachableCodeDetection {
|
||||
>UnreachableCodeDetection : Symbol(UnreachableCodeDetection, Decl(inKeywordTypeguard.ts, 86, 1))
|
||||
|
||||
a: string;
|
||||
>a : Symbol(UnreachableCodeDetection.a, Decl(inKeywordTypeguard.ts, 88, 32))
|
||||
|
||||
inThis() {
|
||||
>inThis : Symbol(UnreachableCodeDetection.inThis, Decl(inKeywordTypeguard.ts, 89, 14))
|
||||
|
||||
if ("a" in this) {
|
||||
>this : Symbol(UnreachableCodeDetection, Decl(inKeywordTypeguard.ts, 86, 1))
|
||||
|
||||
} else {
|
||||
let y = this.a;
|
||||
>y : Symbol(y, Decl(inKeywordTypeguard.ts, 93, 15))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,318 @@
|
||||
=== tests/cases/compiler/inKeywordTypeguard.ts ===
|
||||
class A { a: string; }
|
||||
>A : A
|
||||
>a : string
|
||||
|
||||
class B { b: string; }
|
||||
>B : B
|
||||
>b : string
|
||||
|
||||
function negativeClassesTest(x: A | B) {
|
||||
>negativeClassesTest : (x: A | B) => void
|
||||
>x : A | B
|
||||
>A : A
|
||||
>B : B
|
||||
|
||||
if ("a" in x) {
|
||||
>"a" in x : boolean
|
||||
>"a" : "a"
|
||||
>x : A | B
|
||||
|
||||
x.b = "1";
|
||||
>x.b = "1" : "1"
|
||||
>x.b : any
|
||||
>x : A
|
||||
>b : any
|
||||
>"1" : "1"
|
||||
|
||||
} else {
|
||||
x.a = "1";
|
||||
>x.a = "1" : "1"
|
||||
>x.a : any
|
||||
>x : B
|
||||
>a : any
|
||||
>"1" : "1"
|
||||
}
|
||||
}
|
||||
|
||||
function positiveClassesTest(x: A | B) {
|
||||
>positiveClassesTest : (x: A | B) => void
|
||||
>x : A | B
|
||||
>A : A
|
||||
>B : B
|
||||
|
||||
if ("a" in x) {
|
||||
>"a" in x : boolean
|
||||
>"a" : "a"
|
||||
>x : A | B
|
||||
|
||||
x.b = "1";
|
||||
>x.b = "1" : "1"
|
||||
>x.b : any
|
||||
>x : A
|
||||
>b : any
|
||||
>"1" : "1"
|
||||
|
||||
} else {
|
||||
x.a = "1";
|
||||
>x.a = "1" : "1"
|
||||
>x.a : any
|
||||
>x : B
|
||||
>a : any
|
||||
>"1" : "1"
|
||||
}
|
||||
}
|
||||
|
||||
class AWithOptionalProp { a?: string; }
|
||||
>AWithOptionalProp : AWithOptionalProp
|
||||
>a : string
|
||||
|
||||
class BWithOptionalProp { b?: string; }
|
||||
>BWithOptionalProp : BWithOptionalProp
|
||||
>b : string
|
||||
|
||||
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
|
||||
>positiveTestClassesWithOptionalProperties : (x: AWithOptionalProp | BWithOptionalProp) => void
|
||||
>x : AWithOptionalProp | BWithOptionalProp
|
||||
>AWithOptionalProp : AWithOptionalProp
|
||||
>BWithOptionalProp : BWithOptionalProp
|
||||
|
||||
if ("a" in x) {
|
||||
>"a" in x : boolean
|
||||
>"a" : "a"
|
||||
>x : AWithOptionalProp | BWithOptionalProp
|
||||
|
||||
x.a = "1";
|
||||
>x.a = "1" : "1"
|
||||
>x.a : string
|
||||
>x : AWithOptionalProp
|
||||
>a : string
|
||||
>"1" : "1"
|
||||
|
||||
} else {
|
||||
x.b = "1";
|
||||
>x.b = "1" : "1"
|
||||
>x.b : any
|
||||
>x : AWithOptionalProp | BWithOptionalProp
|
||||
>b : any
|
||||
>"1" : "1"
|
||||
}
|
||||
}
|
||||
|
||||
class AWithMethod {
|
||||
>AWithMethod : AWithMethod
|
||||
|
||||
a(): string { return ""; }
|
||||
>a : () => string
|
||||
>"" : ""
|
||||
}
|
||||
|
||||
class BWithMethod {
|
||||
>BWithMethod : BWithMethod
|
||||
|
||||
b(): string { return ""; }
|
||||
>b : () => string
|
||||
>"" : ""
|
||||
}
|
||||
|
||||
function negativeTestClassesWithMembers(x: AWithMethod | BWithMethod) {
|
||||
>negativeTestClassesWithMembers : (x: AWithMethod | BWithMethod) => void
|
||||
>x : AWithMethod | BWithMethod
|
||||
>AWithMethod : AWithMethod
|
||||
>BWithMethod : BWithMethod
|
||||
|
||||
if ("a" in x) {
|
||||
>"a" in x : boolean
|
||||
>"a" : "a"
|
||||
>x : AWithMethod | BWithMethod
|
||||
|
||||
x.a();
|
||||
>x.a() : string
|
||||
>x.a : () => string
|
||||
>x : AWithMethod
|
||||
>a : () => string
|
||||
|
||||
x.b();
|
||||
>x.b() : any
|
||||
>x.b : any
|
||||
>x : AWithMethod
|
||||
>b : any
|
||||
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
function negativeTestClassesWithMemberMissingInBothClasses(x: AWithMethod | BWithMethod) {
|
||||
>negativeTestClassesWithMemberMissingInBothClasses : (x: AWithMethod | BWithMethod) => void
|
||||
>x : AWithMethod | BWithMethod
|
||||
>AWithMethod : AWithMethod
|
||||
>BWithMethod : BWithMethod
|
||||
|
||||
if ("c" in x) {
|
||||
>"c" in x : boolean
|
||||
>"c" : "c"
|
||||
>x : AWithMethod | BWithMethod
|
||||
|
||||
x.a();
|
||||
>x.a() : any
|
||||
>x.a : any
|
||||
>x : never
|
||||
>a : any
|
||||
|
||||
x.b();
|
||||
>x.b() : any
|
||||
>x.b : any
|
||||
>x : never
|
||||
>b : any
|
||||
|
||||
} else {
|
||||
x.a();
|
||||
>x.a() : any
|
||||
>x.a : any
|
||||
>x : AWithMethod | BWithMethod
|
||||
>a : any
|
||||
|
||||
x.b();
|
||||
>x.b() : any
|
||||
>x.b : any
|
||||
>x : AWithMethod | BWithMethod
|
||||
>b : any
|
||||
}
|
||||
}
|
||||
|
||||
class C { a: string; }
|
||||
>C : C
|
||||
>a : string
|
||||
|
||||
class D { a: string; }
|
||||
>D : D
|
||||
>a : string
|
||||
|
||||
function negativeMultipleClassesTest(x: A | B | C | D) {
|
||||
>negativeMultipleClassesTest : (x: A | B | C | D) => void
|
||||
>x : A | B | C | D
|
||||
>A : A
|
||||
>B : B
|
||||
>C : C
|
||||
>D : D
|
||||
|
||||
if ("a" in x) {
|
||||
>"a" in x : boolean
|
||||
>"a" : "a"
|
||||
>x : A | B | C | D
|
||||
|
||||
x.b = "1";
|
||||
>x.b = "1" : "1"
|
||||
>x.b : any
|
||||
>x : A | C | D
|
||||
>b : any
|
||||
>"1" : "1"
|
||||
|
||||
} else {
|
||||
x.a = "1";
|
||||
>x.a = "1" : "1"
|
||||
>x.a : any
|
||||
>x : B
|
||||
>a : any
|
||||
>"1" : "1"
|
||||
}
|
||||
}
|
||||
|
||||
class ClassWithUnionProp { prop: A | B }
|
||||
>ClassWithUnionProp : ClassWithUnionProp
|
||||
>prop : A | B
|
||||
>A : A
|
||||
>B : B
|
||||
|
||||
function negativePropTest(x: ClassWithUnionProp) {
|
||||
>negativePropTest : (x: ClassWithUnionProp) => void
|
||||
>x : ClassWithUnionProp
|
||||
>ClassWithUnionProp : ClassWithUnionProp
|
||||
|
||||
if ("a" in x.prop) {
|
||||
>"a" in x.prop : boolean
|
||||
>"a" : "a"
|
||||
>x.prop : A | B
|
||||
>x : ClassWithUnionProp
|
||||
>prop : A | B
|
||||
|
||||
let y: string = x.prop.b;
|
||||
>y : string
|
||||
>x.prop.b : any
|
||||
>x.prop : A
|
||||
>x : ClassWithUnionProp
|
||||
>prop : A
|
||||
>b : any
|
||||
|
||||
} else {
|
||||
let z: string = x.prop.a;
|
||||
>z : string
|
||||
>x.prop.a : any
|
||||
>x.prop : B
|
||||
>x : ClassWithUnionProp
|
||||
>prop : B
|
||||
>a : any
|
||||
}
|
||||
}
|
||||
|
||||
class NegativeClassTest {
|
||||
>NegativeClassTest : NegativeClassTest
|
||||
|
||||
protected prop: A | B;
|
||||
>prop : A | B
|
||||
>A : A
|
||||
>B : B
|
||||
|
||||
inThis() {
|
||||
>inThis : () => void
|
||||
|
||||
if ("a" in this.prop) {
|
||||
>"a" in this.prop : boolean
|
||||
>"a" : "a"
|
||||
>this.prop : A | B
|
||||
>this : this
|
||||
>prop : A | B
|
||||
|
||||
let z: number = this.prop.b;
|
||||
>z : number
|
||||
>this.prop.b : any
|
||||
>this.prop : A
|
||||
>this : this
|
||||
>prop : A
|
||||
>b : any
|
||||
|
||||
} else {
|
||||
let y: string = this.prop.a;
|
||||
>y : string
|
||||
>this.prop.a : any
|
||||
>this.prop : B
|
||||
>this : this
|
||||
>prop : B
|
||||
>a : any
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UnreachableCodeDetection {
|
||||
>UnreachableCodeDetection : UnreachableCodeDetection
|
||||
|
||||
a: string;
|
||||
>a : string
|
||||
|
||||
inThis() {
|
||||
>inThis : () => void
|
||||
|
||||
if ("a" in this) {
|
||||
>"a" in this : boolean
|
||||
>"a" : "a"
|
||||
>this : this
|
||||
|
||||
} else {
|
||||
let y = this.a;
|
||||
>y : any
|
||||
>this.a : any
|
||||
>this : never
|
||||
>a : any
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
//// [typeGuardOfFromPropNameInUnionType.ts]
|
||||
class A { a: string; }
|
||||
class B { b: number; }
|
||||
class C { b: Object; }
|
||||
class D { a: Date; }
|
||||
|
||||
function namedClasses(x: A | B) {
|
||||
if ("a" in x) {
|
||||
x.a = "1";
|
||||
} else {
|
||||
x.b = 1;
|
||||
}
|
||||
}
|
||||
|
||||
function multipleClasses(x: A | B | C | D) {
|
||||
if ("a" in x) {
|
||||
let y: string | Date = x.a;
|
||||
} else {
|
||||
let z: number | Object = x.b;
|
||||
}
|
||||
}
|
||||
|
||||
function anonymousClasses(x: { a: string; } | { b: number; }) {
|
||||
if ("a" in x) {
|
||||
let y: string = x.a;
|
||||
} else {
|
||||
let z: number = x.b;
|
||||
}
|
||||
}
|
||||
|
||||
class AWithOptionalProp { a?: string; }
|
||||
class BWithOptionalProp { b?: string; }
|
||||
|
||||
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
|
||||
if ("a" in x) {
|
||||
x.a = "1";
|
||||
} else {
|
||||
const y: string = x instanceof AWithOptionalProp
|
||||
? x.a
|
||||
: x.b
|
||||
}
|
||||
}
|
||||
|
||||
function inParenthesizedExpression(x: A | B) {
|
||||
if ("a" in (x)) {
|
||||
let y: string = x.a;
|
||||
} else {
|
||||
let z: number = x.b;
|
||||
}
|
||||
}
|
||||
|
||||
class ClassWithUnionProp { prop: A | B; }
|
||||
|
||||
function inProperty(x: ClassWithUnionProp) {
|
||||
if ("a" in x.prop) {
|
||||
let y: string = x.prop.a;
|
||||
} else {
|
||||
let z: number = x.prop.b;
|
||||
}
|
||||
}
|
||||
|
||||
class NestedClassWithProp { outer: ClassWithUnionProp; }
|
||||
|
||||
function innestedProperty(x: NestedClassWithProp) {
|
||||
if ("a" in x.outer.prop) {
|
||||
let y: string = x.outer.prop.a;
|
||||
} else {
|
||||
let z: number = x.outer.prop.b;
|
||||
}
|
||||
}
|
||||
|
||||
class InMemberOfClass {
|
||||
protected prop: A | B;
|
||||
inThis() {
|
||||
if ("a" in this.prop) {
|
||||
let y: string = this.prop.a;
|
||||
} else {
|
||||
let z: number = this.prop.b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// added for completeness
|
||||
class SelfAssert {
|
||||
a: string;
|
||||
inThis() {
|
||||
if ("a" in this) {
|
||||
let y: string = this.a;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//// [typeGuardOfFromPropNameInUnionType.js]
|
||||
var A = /** @class */ (function () {
|
||||
function A() {
|
||||
}
|
||||
return A;
|
||||
}());
|
||||
var B = /** @class */ (function () {
|
||||
function B() {
|
||||
}
|
||||
return B;
|
||||
}());
|
||||
var C = /** @class */ (function () {
|
||||
function C() {
|
||||
}
|
||||
return C;
|
||||
}());
|
||||
var D = /** @class */ (function () {
|
||||
function D() {
|
||||
}
|
||||
return D;
|
||||
}());
|
||||
function namedClasses(x) {
|
||||
if ("a" in x) {
|
||||
x.a = "1";
|
||||
}
|
||||
else {
|
||||
x.b = 1;
|
||||
}
|
||||
}
|
||||
function multipleClasses(x) {
|
||||
if ("a" in x) {
|
||||
var y = x.a;
|
||||
}
|
||||
else {
|
||||
var z = x.b;
|
||||
}
|
||||
}
|
||||
function anonymousClasses(x) {
|
||||
if ("a" in x) {
|
||||
var y = x.a;
|
||||
}
|
||||
else {
|
||||
var z = x.b;
|
||||
}
|
||||
}
|
||||
var AWithOptionalProp = /** @class */ (function () {
|
||||
function AWithOptionalProp() {
|
||||
}
|
||||
return AWithOptionalProp;
|
||||
}());
|
||||
var BWithOptionalProp = /** @class */ (function () {
|
||||
function BWithOptionalProp() {
|
||||
}
|
||||
return BWithOptionalProp;
|
||||
}());
|
||||
function positiveTestClassesWithOptionalProperties(x) {
|
||||
if ("a" in x) {
|
||||
x.a = "1";
|
||||
}
|
||||
else {
|
||||
var y = x instanceof AWithOptionalProp
|
||||
? x.a
|
||||
: x.b;
|
||||
}
|
||||
}
|
||||
function inParenthesizedExpression(x) {
|
||||
if ("a" in (x)) {
|
||||
var y = x.a;
|
||||
}
|
||||
else {
|
||||
var z = x.b;
|
||||
}
|
||||
}
|
||||
var ClassWithUnionProp = /** @class */ (function () {
|
||||
function ClassWithUnionProp() {
|
||||
}
|
||||
return ClassWithUnionProp;
|
||||
}());
|
||||
function inProperty(x) {
|
||||
if ("a" in x.prop) {
|
||||
var y = x.prop.a;
|
||||
}
|
||||
else {
|
||||
var z = x.prop.b;
|
||||
}
|
||||
}
|
||||
var NestedClassWithProp = /** @class */ (function () {
|
||||
function NestedClassWithProp() {
|
||||
}
|
||||
return NestedClassWithProp;
|
||||
}());
|
||||
function innestedProperty(x) {
|
||||
if ("a" in x.outer.prop) {
|
||||
var y = x.outer.prop.a;
|
||||
}
|
||||
else {
|
||||
var z = x.outer.prop.b;
|
||||
}
|
||||
}
|
||||
var InMemberOfClass = /** @class */ (function () {
|
||||
function InMemberOfClass() {
|
||||
}
|
||||
InMemberOfClass.prototype.inThis = function () {
|
||||
if ("a" in this.prop) {
|
||||
var y = this.prop.a;
|
||||
}
|
||||
else {
|
||||
var z = this.prop.b;
|
||||
}
|
||||
};
|
||||
return InMemberOfClass;
|
||||
}());
|
||||
// added for completeness
|
||||
var SelfAssert = /** @class */ (function () {
|
||||
function SelfAssert() {
|
||||
}
|
||||
SelfAssert.prototype.inThis = function () {
|
||||
if ("a" in this) {
|
||||
var y = this.a;
|
||||
}
|
||||
else {
|
||||
}
|
||||
};
|
||||
return SelfAssert;
|
||||
}());
|
||||
@@ -0,0 +1,291 @@
|
||||
=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFromPropNameInUnionType.ts ===
|
||||
class A { a: string; }
|
||||
>A : Symbol(A, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 0))
|
||||
>a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
|
||||
|
||||
class B { b: number; }
|
||||
>B : Symbol(B, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 22))
|
||||
>b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
|
||||
|
||||
class C { b: Object; }
|
||||
>C : Symbol(C, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 22))
|
||||
>b : Symbol(C.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 2, 9))
|
||||
>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
|
||||
class D { a: Date; }
|
||||
>D : Symbol(D, Decl(typeGuardOfFromPropNameInUnionType.ts, 2, 22))
|
||||
>a : Symbol(D.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 3, 9))
|
||||
>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
|
||||
function namedClasses(x: A | B) {
|
||||
>namedClasses : Symbol(namedClasses, Decl(typeGuardOfFromPropNameInUnionType.ts, 3, 20))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 5, 22))
|
||||
>A : Symbol(A, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 0))
|
||||
>B : Symbol(B, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 22))
|
||||
|
||||
if ("a" in x) {
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 5, 22))
|
||||
|
||||
x.a = "1";
|
||||
>x.a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 5, 22))
|
||||
>a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
|
||||
|
||||
} else {
|
||||
x.b = 1;
|
||||
>x.b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 5, 22))
|
||||
>b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
|
||||
}
|
||||
}
|
||||
|
||||
function multipleClasses(x: A | B | C | D) {
|
||||
>multipleClasses : Symbol(multipleClasses, Decl(typeGuardOfFromPropNameInUnionType.ts, 11, 1))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 13, 25))
|
||||
>A : Symbol(A, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 0))
|
||||
>B : Symbol(B, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 22))
|
||||
>C : Symbol(C, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 22))
|
||||
>D : Symbol(D, Decl(typeGuardOfFromPropNameInUnionType.ts, 2, 22))
|
||||
|
||||
if ("a" in x) {
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 13, 25))
|
||||
|
||||
let y: string | Date = x.a;
|
||||
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 15, 11))
|
||||
>Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>x.a : Symbol(a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9), Decl(typeGuardOfFromPropNameInUnionType.ts, 3, 9))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 13, 25))
|
||||
>a : Symbol(a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9), Decl(typeGuardOfFromPropNameInUnionType.ts, 3, 9))
|
||||
|
||||
} else {
|
||||
let z: number | Object = x.b;
|
||||
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 17, 11))
|
||||
>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>x.b : Symbol(b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9), Decl(typeGuardOfFromPropNameInUnionType.ts, 2, 9))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 13, 25))
|
||||
>b : Symbol(b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9), Decl(typeGuardOfFromPropNameInUnionType.ts, 2, 9))
|
||||
}
|
||||
}
|
||||
|
||||
function anonymousClasses(x: { a: string; } | { b: number; }) {
|
||||
>anonymousClasses : Symbol(anonymousClasses, Decl(typeGuardOfFromPropNameInUnionType.ts, 19, 1))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 26))
|
||||
>a : Symbol(a, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 30))
|
||||
>b : Symbol(b, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 47))
|
||||
|
||||
if ("a" in x) {
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 26))
|
||||
|
||||
let y: string = x.a;
|
||||
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 23, 11))
|
||||
>x.a : Symbol(a, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 30))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 26))
|
||||
>a : Symbol(a, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 30))
|
||||
|
||||
} else {
|
||||
let z: number = x.b;
|
||||
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 25, 11))
|
||||
>x.b : Symbol(b, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 47))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 26))
|
||||
>b : Symbol(b, Decl(typeGuardOfFromPropNameInUnionType.ts, 21, 47))
|
||||
}
|
||||
}
|
||||
|
||||
class AWithOptionalProp { a?: string; }
|
||||
>AWithOptionalProp : Symbol(AWithOptionalProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 27, 1))
|
||||
>a : Symbol(AWithOptionalProp.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 25))
|
||||
|
||||
class BWithOptionalProp { b?: string; }
|
||||
>BWithOptionalProp : Symbol(BWithOptionalProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 39))
|
||||
>b : Symbol(BWithOptionalProp.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 30, 25))
|
||||
|
||||
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
|
||||
>positiveTestClassesWithOptionalProperties : Symbol(positiveTestClassesWithOptionalProperties, Decl(typeGuardOfFromPropNameInUnionType.ts, 30, 39))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 32, 51))
|
||||
>AWithOptionalProp : Symbol(AWithOptionalProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 27, 1))
|
||||
>BWithOptionalProp : Symbol(BWithOptionalProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 39))
|
||||
|
||||
if ("a" in x) {
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 32, 51))
|
||||
|
||||
x.a = "1";
|
||||
>x.a : Symbol(AWithOptionalProp.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 25))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 32, 51))
|
||||
>a : Symbol(AWithOptionalProp.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 25))
|
||||
|
||||
} else {
|
||||
const y: string = x instanceof AWithOptionalProp
|
||||
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 36, 13))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 32, 51))
|
||||
>AWithOptionalProp : Symbol(AWithOptionalProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 27, 1))
|
||||
|
||||
? x.a
|
||||
>x.a : Symbol(AWithOptionalProp.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 25))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 32, 51))
|
||||
>a : Symbol(AWithOptionalProp.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 29, 25))
|
||||
|
||||
: x.b
|
||||
>x.b : Symbol(BWithOptionalProp.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 30, 25))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 32, 51))
|
||||
>b : Symbol(BWithOptionalProp.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 30, 25))
|
||||
}
|
||||
}
|
||||
|
||||
function inParenthesizedExpression(x: A | B) {
|
||||
>inParenthesizedExpression : Symbol(inParenthesizedExpression, Decl(typeGuardOfFromPropNameInUnionType.ts, 40, 1))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 42, 35))
|
||||
>A : Symbol(A, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 0))
|
||||
>B : Symbol(B, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 22))
|
||||
|
||||
if ("a" in (x)) {
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 42, 35))
|
||||
|
||||
let y: string = x.a;
|
||||
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 44, 11))
|
||||
>x.a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 42, 35))
|
||||
>a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
|
||||
|
||||
} else {
|
||||
let z: number = x.b;
|
||||
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 46, 11))
|
||||
>x.b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 42, 35))
|
||||
>b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
|
||||
}
|
||||
}
|
||||
|
||||
class ClassWithUnionProp { prop: A | B; }
|
||||
>ClassWithUnionProp : Symbol(ClassWithUnionProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 48, 1))
|
||||
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
|
||||
>A : Symbol(A, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 0))
|
||||
>B : Symbol(B, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 22))
|
||||
|
||||
function inProperty(x: ClassWithUnionProp) {
|
||||
>inProperty : Symbol(inProperty, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 41))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 52, 20))
|
||||
>ClassWithUnionProp : Symbol(ClassWithUnionProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 48, 1))
|
||||
|
||||
if ("a" in x.prop) {
|
||||
>x.prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 52, 20))
|
||||
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
|
||||
|
||||
let y: string = x.prop.a;
|
||||
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 54, 11))
|
||||
>x.prop.a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
|
||||
>x.prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 52, 20))
|
||||
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
|
||||
>a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
|
||||
|
||||
} else {
|
||||
let z: number = x.prop.b;
|
||||
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 56, 11))
|
||||
>x.prop.b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
|
||||
>x.prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 52, 20))
|
||||
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
|
||||
>b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
|
||||
}
|
||||
}
|
||||
|
||||
class NestedClassWithProp { outer: ClassWithUnionProp; }
|
||||
>NestedClassWithProp : Symbol(NestedClassWithProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 58, 1))
|
||||
>outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
|
||||
>ClassWithUnionProp : Symbol(ClassWithUnionProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 48, 1))
|
||||
|
||||
function innestedProperty(x: NestedClassWithProp) {
|
||||
>innestedProperty : Symbol(innestedProperty, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 56))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 62, 26))
|
||||
>NestedClassWithProp : Symbol(NestedClassWithProp, Decl(typeGuardOfFromPropNameInUnionType.ts, 58, 1))
|
||||
|
||||
if ("a" in x.outer.prop) {
|
||||
>x.outer.prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
|
||||
>x.outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 62, 26))
|
||||
>outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
|
||||
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
|
||||
|
||||
let y: string = x.outer.prop.a;
|
||||
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 64, 11))
|
||||
>x.outer.prop.a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
|
||||
>x.outer.prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
|
||||
>x.outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 62, 26))
|
||||
>outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
|
||||
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
|
||||
>a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
|
||||
|
||||
} else {
|
||||
let z: number = x.outer.prop.b;
|
||||
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 66, 11))
|
||||
>x.outer.prop.b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
|
||||
>x.outer.prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
|
||||
>x.outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
|
||||
>x : Symbol(x, Decl(typeGuardOfFromPropNameInUnionType.ts, 62, 26))
|
||||
>outer : Symbol(NestedClassWithProp.outer, Decl(typeGuardOfFromPropNameInUnionType.ts, 60, 27))
|
||||
>prop : Symbol(ClassWithUnionProp.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 50, 26))
|
||||
>b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
|
||||
}
|
||||
}
|
||||
|
||||
class InMemberOfClass {
|
||||
>InMemberOfClass : Symbol(InMemberOfClass, Decl(typeGuardOfFromPropNameInUnionType.ts, 68, 1))
|
||||
|
||||
protected prop: A | B;
|
||||
>prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
|
||||
>A : Symbol(A, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 0))
|
||||
>B : Symbol(B, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 22))
|
||||
|
||||
inThis() {
|
||||
>inThis : Symbol(InMemberOfClass.inThis, Decl(typeGuardOfFromPropNameInUnionType.ts, 71, 26))
|
||||
|
||||
if ("a" in this.prop) {
|
||||
>this.prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
|
||||
>this : Symbol(InMemberOfClass, Decl(typeGuardOfFromPropNameInUnionType.ts, 68, 1))
|
||||
>prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
|
||||
|
||||
let y: string = this.prop.a;
|
||||
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 74, 15))
|
||||
>this.prop.a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
|
||||
>this.prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
|
||||
>this : Symbol(InMemberOfClass, Decl(typeGuardOfFromPropNameInUnionType.ts, 68, 1))
|
||||
>prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
|
||||
>a : Symbol(A.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 0, 9))
|
||||
|
||||
} else {
|
||||
let z: number = this.prop.b;
|
||||
>z : Symbol(z, Decl(typeGuardOfFromPropNameInUnionType.ts, 76, 15))
|
||||
>this.prop.b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
|
||||
>this.prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
|
||||
>this : Symbol(InMemberOfClass, Decl(typeGuardOfFromPropNameInUnionType.ts, 68, 1))
|
||||
>prop : Symbol(InMemberOfClass.prop, Decl(typeGuardOfFromPropNameInUnionType.ts, 70, 23))
|
||||
>b : Symbol(B.b, Decl(typeGuardOfFromPropNameInUnionType.ts, 1, 9))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// added for completeness
|
||||
class SelfAssert {
|
||||
>SelfAssert : Symbol(SelfAssert, Decl(typeGuardOfFromPropNameInUnionType.ts, 79, 1))
|
||||
|
||||
a: string;
|
||||
>a : Symbol(SelfAssert.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 82, 18))
|
||||
|
||||
inThis() {
|
||||
>inThis : Symbol(SelfAssert.inThis, Decl(typeGuardOfFromPropNameInUnionType.ts, 83, 14))
|
||||
|
||||
if ("a" in this) {
|
||||
>this : Symbol(SelfAssert, Decl(typeGuardOfFromPropNameInUnionType.ts, 79, 1))
|
||||
|
||||
let y: string = this.a;
|
||||
>y : Symbol(y, Decl(typeGuardOfFromPropNameInUnionType.ts, 86, 15))
|
||||
>this.a : Symbol(SelfAssert.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 82, 18))
|
||||
>this : Symbol(SelfAssert, Decl(typeGuardOfFromPropNameInUnionType.ts, 79, 1))
|
||||
>a : Symbol(SelfAssert.a, Decl(typeGuardOfFromPropNameInUnionType.ts, 82, 18))
|
||||
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,318 @@
|
||||
=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFromPropNameInUnionType.ts ===
|
||||
class A { a: string; }
|
||||
>A : A
|
||||
>a : string
|
||||
|
||||
class B { b: number; }
|
||||
>B : B
|
||||
>b : number
|
||||
|
||||
class C { b: Object; }
|
||||
>C : C
|
||||
>b : Object
|
||||
>Object : Object
|
||||
|
||||
class D { a: Date; }
|
||||
>D : D
|
||||
>a : Date
|
||||
>Date : Date
|
||||
|
||||
function namedClasses(x: A | B) {
|
||||
>namedClasses : (x: A | B) => void
|
||||
>x : A | B
|
||||
>A : A
|
||||
>B : B
|
||||
|
||||
if ("a" in x) {
|
||||
>"a" in x : boolean
|
||||
>"a" : "a"
|
||||
>x : A | B
|
||||
|
||||
x.a = "1";
|
||||
>x.a = "1" : "1"
|
||||
>x.a : string
|
||||
>x : A
|
||||
>a : string
|
||||
>"1" : "1"
|
||||
|
||||
} else {
|
||||
x.b = 1;
|
||||
>x.b = 1 : 1
|
||||
>x.b : number
|
||||
>x : B
|
||||
>b : number
|
||||
>1 : 1
|
||||
}
|
||||
}
|
||||
|
||||
function multipleClasses(x: A | B | C | D) {
|
||||
>multipleClasses : (x: A | B | C | D) => void
|
||||
>x : A | B | C | D
|
||||
>A : A
|
||||
>B : B
|
||||
>C : C
|
||||
>D : D
|
||||
|
||||
if ("a" in x) {
|
||||
>"a" in x : boolean
|
||||
>"a" : "a"
|
||||
>x : A | B | C | D
|
||||
|
||||
let y: string | Date = x.a;
|
||||
>y : string | Date
|
||||
>Date : Date
|
||||
>x.a : string | Date
|
||||
>x : A | D
|
||||
>a : string | Date
|
||||
|
||||
} else {
|
||||
let z: number | Object = x.b;
|
||||
>z : number | Object
|
||||
>Object : Object
|
||||
>x.b : number | Object
|
||||
>x : B | C
|
||||
>b : number | Object
|
||||
}
|
||||
}
|
||||
|
||||
function anonymousClasses(x: { a: string; } | { b: number; }) {
|
||||
>anonymousClasses : (x: { a: string; } | { b: number; }) => void
|
||||
>x : { a: string; } | { b: number; }
|
||||
>a : string
|
||||
>b : number
|
||||
|
||||
if ("a" in x) {
|
||||
>"a" in x : boolean
|
||||
>"a" : "a"
|
||||
>x : { a: string; } | { b: number; }
|
||||
|
||||
let y: string = x.a;
|
||||
>y : string
|
||||
>x.a : string
|
||||
>x : { a: string; }
|
||||
>a : string
|
||||
|
||||
} else {
|
||||
let z: number = x.b;
|
||||
>z : number
|
||||
>x.b : number
|
||||
>x : { b: number; }
|
||||
>b : number
|
||||
}
|
||||
}
|
||||
|
||||
class AWithOptionalProp { a?: string; }
|
||||
>AWithOptionalProp : AWithOptionalProp
|
||||
>a : string
|
||||
|
||||
class BWithOptionalProp { b?: string; }
|
||||
>BWithOptionalProp : BWithOptionalProp
|
||||
>b : string
|
||||
|
||||
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
|
||||
>positiveTestClassesWithOptionalProperties : (x: AWithOptionalProp | BWithOptionalProp) => void
|
||||
>x : AWithOptionalProp | BWithOptionalProp
|
||||
>AWithOptionalProp : AWithOptionalProp
|
||||
>BWithOptionalProp : BWithOptionalProp
|
||||
|
||||
if ("a" in x) {
|
||||
>"a" in x : boolean
|
||||
>"a" : "a"
|
||||
>x : AWithOptionalProp | BWithOptionalProp
|
||||
|
||||
x.a = "1";
|
||||
>x.a = "1" : "1"
|
||||
>x.a : string
|
||||
>x : AWithOptionalProp
|
||||
>a : string
|
||||
>"1" : "1"
|
||||
|
||||
} else {
|
||||
const y: string = x instanceof AWithOptionalProp
|
||||
>y : string
|
||||
>x instanceof AWithOptionalProp ? x.a : x.b : string
|
||||
>x instanceof AWithOptionalProp : boolean
|
||||
>x : AWithOptionalProp | BWithOptionalProp
|
||||
>AWithOptionalProp : typeof AWithOptionalProp
|
||||
|
||||
? x.a
|
||||
>x.a : string
|
||||
>x : AWithOptionalProp
|
||||
>a : string
|
||||
|
||||
: x.b
|
||||
>x.b : string
|
||||
>x : BWithOptionalProp
|
||||
>b : string
|
||||
}
|
||||
}
|
||||
|
||||
function inParenthesizedExpression(x: A | B) {
|
||||
>inParenthesizedExpression : (x: A | B) => void
|
||||
>x : A | B
|
||||
>A : A
|
||||
>B : B
|
||||
|
||||
if ("a" in (x)) {
|
||||
>"a" in (x) : boolean
|
||||
>"a" : "a"
|
||||
>(x) : A | B
|
||||
>x : A | B
|
||||
|
||||
let y: string = x.a;
|
||||
>y : string
|
||||
>x.a : string
|
||||
>x : A
|
||||
>a : string
|
||||
|
||||
} else {
|
||||
let z: number = x.b;
|
||||
>z : number
|
||||
>x.b : number
|
||||
>x : B
|
||||
>b : number
|
||||
}
|
||||
}
|
||||
|
||||
class ClassWithUnionProp { prop: A | B; }
|
||||
>ClassWithUnionProp : ClassWithUnionProp
|
||||
>prop : A | B
|
||||
>A : A
|
||||
>B : B
|
||||
|
||||
function inProperty(x: ClassWithUnionProp) {
|
||||
>inProperty : (x: ClassWithUnionProp) => void
|
||||
>x : ClassWithUnionProp
|
||||
>ClassWithUnionProp : ClassWithUnionProp
|
||||
|
||||
if ("a" in x.prop) {
|
||||
>"a" in x.prop : boolean
|
||||
>"a" : "a"
|
||||
>x.prop : A | B
|
||||
>x : ClassWithUnionProp
|
||||
>prop : A | B
|
||||
|
||||
let y: string = x.prop.a;
|
||||
>y : string
|
||||
>x.prop.a : string
|
||||
>x.prop : A
|
||||
>x : ClassWithUnionProp
|
||||
>prop : A
|
||||
>a : string
|
||||
|
||||
} else {
|
||||
let z: number = x.prop.b;
|
||||
>z : number
|
||||
>x.prop.b : number
|
||||
>x.prop : B
|
||||
>x : ClassWithUnionProp
|
||||
>prop : B
|
||||
>b : number
|
||||
}
|
||||
}
|
||||
|
||||
class NestedClassWithProp { outer: ClassWithUnionProp; }
|
||||
>NestedClassWithProp : NestedClassWithProp
|
||||
>outer : ClassWithUnionProp
|
||||
>ClassWithUnionProp : ClassWithUnionProp
|
||||
|
||||
function innestedProperty(x: NestedClassWithProp) {
|
||||
>innestedProperty : (x: NestedClassWithProp) => void
|
||||
>x : NestedClassWithProp
|
||||
>NestedClassWithProp : NestedClassWithProp
|
||||
|
||||
if ("a" in x.outer.prop) {
|
||||
>"a" in x.outer.prop : boolean
|
||||
>"a" : "a"
|
||||
>x.outer.prop : A | B
|
||||
>x.outer : ClassWithUnionProp
|
||||
>x : NestedClassWithProp
|
||||
>outer : ClassWithUnionProp
|
||||
>prop : A | B
|
||||
|
||||
let y: string = x.outer.prop.a;
|
||||
>y : string
|
||||
>x.outer.prop.a : string
|
||||
>x.outer.prop : A
|
||||
>x.outer : ClassWithUnionProp
|
||||
>x : NestedClassWithProp
|
||||
>outer : ClassWithUnionProp
|
||||
>prop : A
|
||||
>a : string
|
||||
|
||||
} else {
|
||||
let z: number = x.outer.prop.b;
|
||||
>z : number
|
||||
>x.outer.prop.b : number
|
||||
>x.outer.prop : B
|
||||
>x.outer : ClassWithUnionProp
|
||||
>x : NestedClassWithProp
|
||||
>outer : ClassWithUnionProp
|
||||
>prop : B
|
||||
>b : number
|
||||
}
|
||||
}
|
||||
|
||||
class InMemberOfClass {
|
||||
>InMemberOfClass : InMemberOfClass
|
||||
|
||||
protected prop: A | B;
|
||||
>prop : A | B
|
||||
>A : A
|
||||
>B : B
|
||||
|
||||
inThis() {
|
||||
>inThis : () => void
|
||||
|
||||
if ("a" in this.prop) {
|
||||
>"a" in this.prop : boolean
|
||||
>"a" : "a"
|
||||
>this.prop : A | B
|
||||
>this : this
|
||||
>prop : A | B
|
||||
|
||||
let y: string = this.prop.a;
|
||||
>y : string
|
||||
>this.prop.a : string
|
||||
>this.prop : A
|
||||
>this : this
|
||||
>prop : A
|
||||
>a : string
|
||||
|
||||
} else {
|
||||
let z: number = this.prop.b;
|
||||
>z : number
|
||||
>this.prop.b : number
|
||||
>this.prop : B
|
||||
>this : this
|
||||
>prop : B
|
||||
>b : number
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// added for completeness
|
||||
class SelfAssert {
|
||||
>SelfAssert : SelfAssert
|
||||
|
||||
a: string;
|
||||
>a : string
|
||||
|
||||
inThis() {
|
||||
>inThis : () => void
|
||||
|
||||
if ("a" in this) {
|
||||
>"a" in this : boolean
|
||||
>"a" : "a"
|
||||
>this : this
|
||||
|
||||
let y: string = this.a;
|
||||
>y : string
|
||||
>this.a : string
|
||||
>this : this
|
||||
>a : string
|
||||
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
class A { a: string; }
|
||||
class B { b: string; }
|
||||
|
||||
function negativeClassesTest(x: A | B) {
|
||||
if ("a" in x) {
|
||||
x.b = "1";
|
||||
} else {
|
||||
x.a = "1";
|
||||
}
|
||||
}
|
||||
|
||||
function positiveClassesTest(x: A | B) {
|
||||
if ("a" in x) {
|
||||
x.b = "1";
|
||||
} else {
|
||||
x.a = "1";
|
||||
}
|
||||
}
|
||||
|
||||
class AWithOptionalProp { a?: string; }
|
||||
class BWithOptionalProp { b?: string; }
|
||||
|
||||
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
|
||||
if ("a" in x) {
|
||||
x.a = "1";
|
||||
} else {
|
||||
x.b = "1";
|
||||
}
|
||||
}
|
||||
|
||||
class AWithMethod {
|
||||
a(): string { return ""; }
|
||||
}
|
||||
|
||||
class BWithMethod {
|
||||
b(): string { return ""; }
|
||||
}
|
||||
|
||||
function negativeTestClassesWithMembers(x: AWithMethod | BWithMethod) {
|
||||
if ("a" in x) {
|
||||
x.a();
|
||||
x.b();
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
function negativeTestClassesWithMemberMissingInBothClasses(x: AWithMethod | BWithMethod) {
|
||||
if ("c" in x) {
|
||||
x.a();
|
||||
x.b();
|
||||
} else {
|
||||
x.a();
|
||||
x.b();
|
||||
}
|
||||
}
|
||||
|
||||
class C { a: string; }
|
||||
class D { a: string; }
|
||||
|
||||
function negativeMultipleClassesTest(x: A | B | C | D) {
|
||||
if ("a" in x) {
|
||||
x.b = "1";
|
||||
} else {
|
||||
x.a = "1";
|
||||
}
|
||||
}
|
||||
|
||||
class ClassWithUnionProp { prop: A | B }
|
||||
|
||||
function negativePropTest(x: ClassWithUnionProp) {
|
||||
if ("a" in x.prop) {
|
||||
let y: string = x.prop.b;
|
||||
} else {
|
||||
let z: string = x.prop.a;
|
||||
}
|
||||
}
|
||||
|
||||
class NegativeClassTest {
|
||||
protected prop: A | B;
|
||||
inThis() {
|
||||
if ("a" in this.prop) {
|
||||
let z: number = this.prop.b;
|
||||
} else {
|
||||
let y: string = this.prop.a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UnreachableCodeDetection {
|
||||
a: string;
|
||||
inThis() {
|
||||
if ("a" in this) {
|
||||
} else {
|
||||
let y = this.a;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
class A { a: string; }
|
||||
class B { b: number; }
|
||||
class C { b: Object; }
|
||||
class D { a: Date; }
|
||||
|
||||
function namedClasses(x: A | B) {
|
||||
if ("a" in x) {
|
||||
x.a = "1";
|
||||
} else {
|
||||
x.b = 1;
|
||||
}
|
||||
}
|
||||
|
||||
function multipleClasses(x: A | B | C | D) {
|
||||
if ("a" in x) {
|
||||
let y: string | Date = x.a;
|
||||
} else {
|
||||
let z: number | Object = x.b;
|
||||
}
|
||||
}
|
||||
|
||||
function anonymousClasses(x: { a: string; } | { b: number; }) {
|
||||
if ("a" in x) {
|
||||
let y: string = x.a;
|
||||
} else {
|
||||
let z: number = x.b;
|
||||
}
|
||||
}
|
||||
|
||||
class AWithOptionalProp { a?: string; }
|
||||
class BWithOptionalProp { b?: string; }
|
||||
|
||||
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
|
||||
if ("a" in x) {
|
||||
x.a = "1";
|
||||
} else {
|
||||
const y: string = x instanceof AWithOptionalProp
|
||||
? x.a
|
||||
: x.b
|
||||
}
|
||||
}
|
||||
|
||||
function inParenthesizedExpression(x: A | B) {
|
||||
if ("a" in (x)) {
|
||||
let y: string = x.a;
|
||||
} else {
|
||||
let z: number = x.b;
|
||||
}
|
||||
}
|
||||
|
||||
class ClassWithUnionProp { prop: A | B; }
|
||||
|
||||
function inProperty(x: ClassWithUnionProp) {
|
||||
if ("a" in x.prop) {
|
||||
let y: string = x.prop.a;
|
||||
} else {
|
||||
let z: number = x.prop.b;
|
||||
}
|
||||
}
|
||||
|
||||
class NestedClassWithProp { outer: ClassWithUnionProp; }
|
||||
|
||||
function innestedProperty(x: NestedClassWithProp) {
|
||||
if ("a" in x.outer.prop) {
|
||||
let y: string = x.outer.prop.a;
|
||||
} else {
|
||||
let z: number = x.outer.prop.b;
|
||||
}
|
||||
}
|
||||
|
||||
class InMemberOfClass {
|
||||
protected prop: A | B;
|
||||
inThis() {
|
||||
if ("a" in this.prop) {
|
||||
let y: string = this.prop.a;
|
||||
} else {
|
||||
let z: number = this.prop.b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// added for completeness
|
||||
class SelfAssert {
|
||||
a: string;
|
||||
inThis() {
|
||||
if ("a" in this) {
|
||||
let y: string = this.a;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/// <reference path="fourslash.ts"/>
|
||||
|
||||
//// label: while (true) {
|
||||
//// break /*1*/
|
||||
//// continue /*2*/
|
||||
//// testlabel: while (true) {
|
||||
//// break /*3*/
|
||||
//// continue /*4*/
|
||||
//// break tes/*5*/
|
||||
//// continue tes/*6*/
|
||||
//// }
|
||||
//// break /*7*/
|
||||
//// break; /*8*/
|
||||
////}
|
||||
|
||||
goTo.marker("1");
|
||||
verify.completionListContains("label");
|
||||
|
||||
goTo.marker("2");
|
||||
verify.completionListContains("label");
|
||||
verify.not.completionListContains("testlabel");
|
||||
|
||||
goTo.marker("3");
|
||||
verify.completionListContains("label");
|
||||
verify.completionListContains("testlabel");
|
||||
|
||||
goTo.marker("4");
|
||||
verify.completionListContains("label");
|
||||
verify.completionListContains("testlabel");
|
||||
|
||||
goTo.marker("5");
|
||||
verify.completionListContains("testlabel");
|
||||
verify.completionListContains("label");
|
||||
|
||||
goTo.marker("6");
|
||||
verify.completionListContains("testlabel");
|
||||
verify.completionListContains("label");
|
||||
|
||||
goTo.marker("7");
|
||||
verify.completionListContains("label");
|
||||
verify.not.completionListContains("testlabel");
|
||||
|
||||
goTo.marker("8");
|
||||
verify.not.completionListContains("label");
|
||||
Reference in New Issue
Block a user