Merge branch 'master' into disallow-global-umd-merges
This commit is contained in:
commit
98df06dde8
37
.github/workflows/ci.yml
vendored
Normal file
37
.github/workflows/ci.yml
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [8.x, 10.x, 12.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
fetch-depth: 5
|
||||
- name: Use node version ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Remove existing TypeScript
|
||||
run: |
|
||||
npm uninstall typescript --no-save
|
||||
npm uninstall tslint --no-save
|
||||
- name: npm install and test
|
||||
run: |
|
||||
npm install
|
||||
npm update
|
||||
npm test
|
29
.vscode/launch.template.json
vendored
29
.vscode/launch.template.json
vendored
|
@ -1,5 +1,17 @@
|
|||
// Rename this file 'launch.json' or merge its
|
||||
// contents into your existing configurations.
|
||||
/*
|
||||
|
||||
Copy this file into '.vscode/launch.json' or merge its
|
||||
contents into your existing configurations.
|
||||
|
||||
If you want to remove the errors in comments for all JSON
|
||||
files, add this to your settings in ~/.vscode/User/settings.json
|
||||
|
||||
"files.associations": {
|
||||
"*.json": "jsonc"
|
||||
},
|
||||
|
||||
*/
|
||||
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
|
@ -10,7 +22,7 @@
|
|||
"type": "node",
|
||||
"protocol": "inspector",
|
||||
"request": "launch",
|
||||
"name": "Mocha Tests (currently opened test)",
|
||||
"name": "Mocha Tests (currently opened test)",
|
||||
"runtimeArgs": ["--nolazy"],
|
||||
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
|
||||
"args": [
|
||||
|
@ -20,6 +32,8 @@
|
|||
"--colors",
|
||||
"built/local/run.js",
|
||||
"-f",
|
||||
// You can change this to be the name of a specific test file (without the file extension)
|
||||
// to consistently launch the same test
|
||||
"${fileBasenameNoExtension}",
|
||||
"--skip-percent",
|
||||
"0"
|
||||
|
@ -34,6 +48,13 @@
|
|||
"outFiles": [
|
||||
"${workspaceRoot}/built/local/run.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
// See: https://github.com/microsoft/TypeScript/wiki/Debugging-Language-Service-in-VS-Code
|
||||
"type": "node",
|
||||
"request": "attach",
|
||||
"name": "Attach to VS Code TS Server via Port",
|
||||
"processId": "${command:PickProcess}"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,11 +59,11 @@ Run `gulp` to build a version of the compiler/language service that reflects cha
|
|||
|
||||
## Contributing bug fixes
|
||||
|
||||
TypeScript is currently accepting contributions in the form of bug fixes. A bug must have an issue tracking it in the issue tracker that has been approved (labelled ["help wanted"](https://github.com/Microsoft/TypeScript/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)) by the TypeScript team. Your pull request should include a link to the bug that you are fixing. If you've submitted a PR for a bug, please post a comment in the bug to avoid duplication of effort.
|
||||
TypeScript is currently accepting contributions in the form of bug fixes. A bug must have an issue tracking it in the issue tracker that has been approved (labelled ["help wanted"](https://github.com/Microsoft/TypeScript/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) or in the "Backlog milestone") by the TypeScript team. Your pull request should include a link to the bug that you are fixing. If you've submitted a PR for a bug, please post a comment in the bug to avoid duplication of effort.
|
||||
|
||||
## Contributing features
|
||||
|
||||
Features (things that add new or improved functionality to TypeScript) may be accepted, but will need to first be approved ([labelled "help wanted"](https://github.com/Microsoft/TypeScript/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) by a TypeScript project maintainer) in the suggestion issue. Features with language design impact, or that are adequately satisfied with external tools, will not be accepted.
|
||||
Features (things that add new or improved functionality to TypeScript) may be accepted, but will need to first be approved ([labelled "help wanted"](https://github.com/Microsoft/TypeScript/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22 or in the "Backlog" milestone) by a TypeScript project maintainer) in the suggestion issue. Features with language design impact, or that are adequately satisfied with external tools, will not be accepted.
|
||||
|
||||
Design changes will not be accepted at this time. If you have a design change proposal, please log a suggestion issue.
|
||||
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
|
||||
# TypeScript
|
||||
|
||||
[![Join the chat at https://gitter.im/microsoft/TypeScript](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/microsoft/TypeScript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[![Build Status](https://travis-ci.org/microsoft/TypeScript.svg?branch=master)](https://travis-ci.org/microsoft/TypeScript)
|
||||
[![VSTS Build Status](https://dev.azure.com/typescript/TypeScript/_apis/build/status/Typescript/node10)](https://dev.azure.com/typescript/TypeScript/_build/latest?definitionId=4&view=logs)
|
||||
[![npm version](https://badge.fury.io/js/typescript.svg)](https://www.npmjs.com/package/typescript)
|
||||
[![Downloads](https://img.shields.io/npm/dm/typescript.svg)](https://www.npmjs.com/package/typescript)
|
||||
|
||||
|
||||
|
||||
[TypeScript](https://www.typescriptlang.org/) is a language for application-scale JavaScript. TypeScript adds optional types to JavaScript that support tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScript. Try it out at the [playground](https://www.typescriptlang.org/play/), and stay up to date via [our blog](https://blogs.msdn.microsoft.com/typescript) and [Twitter account](https://twitter.com/typescript).
|
||||
|
||||
Find others who are using TypeScript at [our community page](https://www.typescriptlang.org/community/).
|
||||
|
||||
## Installing
|
||||
|
||||
For the latest stable version:
|
||||
|
@ -31,6 +30,7 @@ There are many ways to [contribute](https://github.com/microsoft/TypeScript/blob
|
|||
* [Submit bugs](https://github.com/microsoft/TypeScript/issues) and help us verify fixes as they are checked in.
|
||||
* Review the [source code changes](https://github.com/microsoft/TypeScript/pulls).
|
||||
* Engage with other TypeScript users and developers on [StackOverflow](https://stackoverflow.com/questions/tagged/typescript).
|
||||
* Help each other in the [TypeScript Community Discord](https://discord.gg/typescript).
|
||||
* Join the [#typescript](https://twitter.com/search?q=%23TypeScript) discussion on Twitter.
|
||||
* [Contribute bug fixes](https://github.com/microsoft/TypeScript/blob/master/CONTRIBUTING.md).
|
||||
* Read the language specification ([docx](https://github.com/microsoft/TypeScript/blob/master/doc/TypeScript%20Language%20Specification.docx?raw=true),
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "typescript",
|
||||
"author": "Microsoft Corp.",
|
||||
"homepage": "https://www.typescriptlang.org/",
|
||||
"version": "3.7.0",
|
||||
"version": "3.8.0",
|
||||
"license": "Apache-2.0",
|
||||
"description": "TypeScript is a language for application scale JavaScript development",
|
||||
"keywords": [
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export const enum ModuleInstanceState {
|
||||
|
@ -821,9 +822,6 @@ namespace ts {
|
|||
case SyntaxKind.JSDocEnumTag:
|
||||
bindJSDocTypeAlias(node as JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag);
|
||||
break;
|
||||
case SyntaxKind.JSDocClassTag:
|
||||
bindJSDocClassTag(node as JSDocClassTag);
|
||||
break;
|
||||
// In source files and blocks, bind functions first to match hoisting that occurs at runtime
|
||||
case SyntaxKind.SourceFile: {
|
||||
bindEachFunctionsFirst((node as SourceFile).statements);
|
||||
|
@ -954,11 +952,10 @@ namespace ts {
|
|||
if (!expression) {
|
||||
return flags & FlowFlags.TrueCondition ? antecedent : unreachableFlow;
|
||||
}
|
||||
if (expression.kind === SyntaxKind.TrueKeyword && flags & FlowFlags.FalseCondition ||
|
||||
expression.kind === SyntaxKind.FalseKeyword && flags & FlowFlags.TrueCondition) {
|
||||
if (!isOptionalChainRoot(expression.parent)) {
|
||||
return unreachableFlow;
|
||||
}
|
||||
if ((expression.kind === SyntaxKind.TrueKeyword && flags & FlowFlags.FalseCondition ||
|
||||
expression.kind === SyntaxKind.FalseKeyword && flags & FlowFlags.TrueCondition) &&
|
||||
!isExpressionOfOptionalChainRoot(expression) && !isNullishCoalesce(expression.parent)) {
|
||||
return unreachableFlow;
|
||||
}
|
||||
if (!isNarrowingExpression(expression)) {
|
||||
return antecedent;
|
||||
|
@ -2006,7 +2003,12 @@ namespace ts {
|
|||
switch (getAssignmentDeclarationPropertyAccessKind(declName.parent)) {
|
||||
case AssignmentDeclarationKind.ExportsProperty:
|
||||
case AssignmentDeclarationKind.ModuleExports:
|
||||
container = file;
|
||||
if (!isExternalOrCommonJsModule(file)) {
|
||||
container = undefined!;
|
||||
}
|
||||
else {
|
||||
container = file;
|
||||
}
|
||||
break;
|
||||
case AssignmentDeclarationKind.ThisProperty:
|
||||
container = declName.parent.expression;
|
||||
|
@ -2020,7 +2022,9 @@ namespace ts {
|
|||
case AssignmentDeclarationKind.None:
|
||||
return Debug.fail("Shouldn't have detected typedef or enum on non-assignment declaration");
|
||||
}
|
||||
declareModuleMember(typeAlias, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
|
||||
if (container) {
|
||||
declareModuleMember(typeAlias, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
|
||||
}
|
||||
container = oldContainer;
|
||||
}
|
||||
}
|
||||
|
@ -2454,6 +2458,8 @@ namespace ts {
|
|||
case SyntaxKind.JSDocTypeLiteral:
|
||||
case SyntaxKind.MappedType:
|
||||
return bindAnonymousTypeWorker(node as TypeLiteralNode | MappedTypeNode | JSDocTypeLiteral);
|
||||
case SyntaxKind.JSDocClassTag:
|
||||
return bindJSDocClassTag(node as JSDocClassTag);
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
return bindObjectLiteralExpression(<ObjectLiteralExpression>node);
|
||||
case SyntaxKind.FunctionExpression:
|
||||
|
@ -2691,7 +2697,8 @@ namespace ts {
|
|||
const flags = exportAssignmentIsAlias(node)
|
||||
? SymbolFlags.Alias // An export= with an EntityNameExpression or a ClassExpression exports all meanings of that identifier or class
|
||||
: SymbolFlags.Property | SymbolFlags.ExportValue | SymbolFlags.ValueModule;
|
||||
declareSymbol(file.symbol.exports!, file.symbol, node, flags | SymbolFlags.Assignment, SymbolFlags.None);
|
||||
const symbol = declareSymbol(file.symbol.exports!, file.symbol, node, flags | SymbolFlags.Assignment, SymbolFlags.None);
|
||||
setValueDeclaration(symbol, node);
|
||||
}
|
||||
|
||||
function bindThisPropertyAssignment(node: BindablePropertyAssignmentExpression | PropertyAccessExpression | LiteralLikeElementAccessExpression) {
|
||||
|
@ -2709,7 +2716,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
if (constructorSymbol) {
|
||||
if (constructorSymbol && constructorSymbol.valueDeclaration) {
|
||||
// Declare a 'member' if the container is an ES5 class or ES6 constructor
|
||||
constructorSymbol.members = constructorSymbol.members || createSymbolTable();
|
||||
// It's acceptable for multiple 'this' assignments of the same identifier to occur
|
||||
|
@ -2789,6 +2796,10 @@ namespace ts {
|
|||
|
||||
function bindObjectDefinePrototypeProperty(node: BindableObjectDefinePropertyCall) {
|
||||
const namespaceSymbol = lookupSymbolForPropertyAccess((node.arguments[0] as PropertyAccessExpression).expression as EntityNameExpression);
|
||||
if (namespaceSymbol) {
|
||||
// Ensure the namespace symbol becomes class-like
|
||||
addDeclarationToSymbol(namespaceSymbol, namespaceSymbol.valueDeclaration, SymbolFlags.Class);
|
||||
}
|
||||
bindPotentiallyNewExpandoMemberToNamespace(node, namespaceSymbol, /*isPrototypeProperty*/ true);
|
||||
}
|
||||
|
||||
|
|
|
@ -327,10 +327,6 @@ namespace ts {
|
|||
/** This will be set during calls to `getResolvedSignature` where services determines an apparent number of arguments greater than what is actually provided. */
|
||||
let apparentArgumentCount: number | undefined;
|
||||
|
||||
// This object is reused for `checkOptionalExpression` return values to avoid frequent GC due to nursery object allocations.
|
||||
// This object represents a pool-size of 1.
|
||||
const pooledOptionalTypeResult: { isOptional: boolean, type: Type } = { isOptional: false, type: undefined! };
|
||||
|
||||
// for public members that accept a Node or one of its subtypes, we must guard against
|
||||
// synthetic nodes created during transformations by calling `getParseTreeNode`.
|
||||
// for most of these, we perform the guard only on `checker` to avoid any possible
|
||||
|
@ -712,10 +708,10 @@ namespace ts {
|
|||
|
||||
const noTypePredicate = createTypePredicate(TypePredicateKind.Identifier, "<<unresolved>>", 0, anyType);
|
||||
|
||||
const anySignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
|
||||
const unknownSignature = createSignature(undefined, undefined, undefined, emptyArray, errorType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
|
||||
const resolvingSignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
|
||||
const silentNeverSignature = createSignature(undefined, undefined, undefined, emptyArray, silentNeverType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
|
||||
const anySignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None);
|
||||
const unknownSignature = createSignature(undefined, undefined, undefined, emptyArray, errorType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None);
|
||||
const resolvingSignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None);
|
||||
const silentNeverSignature = createSignature(undefined, undefined, undefined, emptyArray, silentNeverType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None);
|
||||
|
||||
const enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true);
|
||||
|
||||
|
@ -2633,7 +2629,12 @@ namespace ts {
|
|||
return undefined;
|
||||
}
|
||||
const init = isVariableDeclaration(decl) ? getDeclaredExpandoInitializer(decl) : getAssignedExpandoInitializer(decl);
|
||||
return init && getSymbolOfNode(init) || undefined;
|
||||
if (init) {
|
||||
const initSymbol = getSymbolOfNode(init);
|
||||
if (initSymbol) {
|
||||
return mergeJSSymbols(initSymbol, symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -4091,8 +4092,6 @@ namespace ts {
|
|||
else if (context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral &&
|
||||
type.symbol.valueDeclaration &&
|
||||
isClassLike(type.symbol.valueDeclaration) &&
|
||||
// Use `import` types for refs to other scopes, only anonymize something defined in the same scope
|
||||
findAncestor(type.symbol.valueDeclaration, d => d === getSourceFileOfNode(context.enclosingDeclaration)) &&
|
||||
!isValueSymbolAccessible(type.symbol, context.enclosingDeclaration)
|
||||
) {
|
||||
return createAnonymousTypeNode(type);
|
||||
|
@ -7680,6 +7679,7 @@ namespace ts {
|
|||
// The outer type parameters are those defined by enclosing generic classes, methods, or functions.
|
||||
function getOuterTypeParametersOfClassOrInterface(symbol: Symbol): TypeParameter[] | undefined {
|
||||
const declaration = symbol.flags & SymbolFlags.Class ? symbol.valueDeclaration : getDeclarationOfKind(symbol, SyntaxKind.InterfaceDeclaration)!;
|
||||
Debug.assert(!!declaration, "Class was missing valueDeclaration -OR- non-class had no interface declarations");
|
||||
return getOuterTypeParameters(declaration);
|
||||
}
|
||||
|
||||
|
@ -7712,7 +7712,7 @@ namespace ts {
|
|||
const signatures = getSignaturesOfType(type, SignatureKind.Construct);
|
||||
if (signatures.length === 1) {
|
||||
const s = signatures[0];
|
||||
return !s.typeParameters && s.parameters.length === 1 && s.hasRestParameter && getElementTypeOfArrayType(getTypeOfParameter(s.parameters[0])) === anyType;
|
||||
return !s.typeParameters && s.parameters.length === 1 && signatureHasRestParameter(s) && getElementTypeOfArrayType(getTypeOfParameter(s.parameters[0])) === anyType;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -8603,10 +8603,9 @@ namespace ts {
|
|||
resolvedReturnType: Type | undefined,
|
||||
resolvedTypePredicate: TypePredicate | undefined,
|
||||
minArgumentCount: number,
|
||||
hasRestParameter: boolean,
|
||||
hasLiteralTypes: boolean,
|
||||
flags: SignatureFlags
|
||||
): Signature {
|
||||
const sig = new Signature(checker);
|
||||
const sig = new Signature(checker, flags);
|
||||
sig.declaration = declaration;
|
||||
sig.typeParameters = typeParameters;
|
||||
sig.parameters = parameters;
|
||||
|
@ -8614,8 +8613,6 @@ namespace ts {
|
|||
sig.resolvedReturnType = resolvedReturnType;
|
||||
sig.resolvedTypePredicate = resolvedTypePredicate;
|
||||
sig.minArgumentCount = minArgumentCount;
|
||||
sig.hasRestParameter = hasRestParameter;
|
||||
sig.hasLiteralTypes = hasLiteralTypes;
|
||||
sig.target = undefined;
|
||||
sig.mapper = undefined;
|
||||
return sig;
|
||||
|
@ -8623,7 +8620,7 @@ namespace ts {
|
|||
|
||||
function cloneSignature(sig: Signature): Signature {
|
||||
const result = createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, /*resolvedReturnType*/ undefined,
|
||||
/*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.hasRestParameter, sig.hasLiteralTypes);
|
||||
/*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.flags & SignatureFlags.PropagatingFlags);
|
||||
result.target = sig.target;
|
||||
result.mapper = sig.mapper;
|
||||
return result;
|
||||
|
@ -8637,14 +8634,19 @@ namespace ts {
|
|||
return result;
|
||||
}
|
||||
|
||||
function getOptionalCallSignature(signature: Signature) {
|
||||
return signatureIsOptionalCall(signature) ? signature :
|
||||
(signature.optionalCallSignatureCache || (signature.optionalCallSignatureCache = createOptionalCallSignature(signature)));
|
||||
}
|
||||
|
||||
function createOptionalCallSignature(signature: Signature) {
|
||||
const result = cloneSignature(signature);
|
||||
result.isOptionalCall = true;
|
||||
result.flags |= SignatureFlags.IsOptionalCall;
|
||||
return result;
|
||||
}
|
||||
|
||||
function getExpandedParameters(sig: Signature): readonly Symbol[] {
|
||||
if (sig.hasRestParameter) {
|
||||
if (signatureHasRestParameter(sig)) {
|
||||
const restIndex = sig.parameters.length - 1;
|
||||
const restParameter = sig.parameters[restIndex];
|
||||
const restType = getTypeOfSymbol(restParameter);
|
||||
|
@ -8670,7 +8672,7 @@ namespace ts {
|
|||
const baseConstructorType = getBaseConstructorTypeOfClass(classType);
|
||||
const baseSignatures = getSignaturesOfType(baseConstructorType, SignatureKind.Construct);
|
||||
if (baseSignatures.length === 0) {
|
||||
return [createSignature(undefined, classType.localTypeParameters, undefined, emptyArray, classType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false)];
|
||||
return [createSignature(undefined, classType.localTypeParameters, undefined, emptyArray, classType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None)];
|
||||
}
|
||||
const baseTypeNode = getBaseTypeNodeOfClass(classType)!;
|
||||
const isJavaScript = isInJSFile(baseTypeNode);
|
||||
|
@ -8834,8 +8836,6 @@ namespace ts {
|
|||
const params = combineUnionParameters(left, right);
|
||||
const thisParam = combineUnionThisParam(left.thisParameter, right.thisParameter);
|
||||
const minArgCount = Math.max(left.minArgumentCount, right.minArgumentCount);
|
||||
const hasRestParam = left.hasRestParameter || right.hasRestParameter;
|
||||
const hasLiteralTypes = left.hasLiteralTypes || right.hasLiteralTypes;
|
||||
const result = createSignature(
|
||||
declaration,
|
||||
left.typeParameters || right.typeParameters,
|
||||
|
@ -8844,8 +8844,7 @@ namespace ts {
|
|||
/*resolvedReturnType*/ undefined,
|
||||
/*resolvedTypePredicate*/ undefined,
|
||||
minArgCount,
|
||||
hasRestParam,
|
||||
hasLiteralTypes
|
||||
(left.flags | right.flags) & SignatureFlags.PropagatingFlags
|
||||
);
|
||||
result.unionSignatures = concatenate(left.unionSignatures || [left], [right]);
|
||||
return result;
|
||||
|
@ -9027,7 +9026,7 @@ namespace ts {
|
|||
constructSignatures = addRange(constructSignatures.slice(), mapDefined(
|
||||
type.callSignatures,
|
||||
sig => isJSConstructor(sig.declaration) ?
|
||||
createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, classType, /*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.hasRestParameter, sig.hasLiteralTypes) :
|
||||
createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, classType, /*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.flags & SignatureFlags.PropagatingFlags) :
|
||||
undefined));
|
||||
}
|
||||
if (!constructSignatures.length) {
|
||||
|
@ -10034,7 +10033,7 @@ namespace ts {
|
|||
const links = getNodeLinks(declaration);
|
||||
if (!links.resolvedSignature) {
|
||||
const parameters: Symbol[] = [];
|
||||
let hasLiteralTypes = false;
|
||||
let flags = SignatureFlags.None;
|
||||
let minArgumentCount = 0;
|
||||
let thisParameter: Symbol | undefined;
|
||||
let hasThisParameter = false;
|
||||
|
@ -10068,7 +10067,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
if (type && type.kind === SyntaxKind.LiteralType) {
|
||||
hasLiteralTypes = true;
|
||||
flags |= SignatureFlags.HasLiteralTypes;
|
||||
}
|
||||
|
||||
// Record a new minimum argument count if this is not an optional parameter
|
||||
|
@ -10097,10 +10096,12 @@ namespace ts {
|
|||
getDeclaredTypeOfClassOrInterface(getMergedSymbol((<ClassDeclaration>declaration.parent).symbol))
|
||||
: undefined;
|
||||
const typeParameters = classType ? classType.localTypeParameters : getTypeParametersFromDeclaration(declaration);
|
||||
const hasRestLikeParameter = hasRestParameter(declaration) || isInJSFile(declaration) && maybeAddJsSyntheticRestParameter(declaration, parameters);
|
||||
if (hasRestParameter(declaration) || isInJSFile(declaration) && maybeAddJsSyntheticRestParameter(declaration, parameters)) {
|
||||
flags |= SignatureFlags.HasRestParameter;
|
||||
}
|
||||
links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters,
|
||||
/*resolvedReturnType*/ undefined, /*resolvedTypePredicate*/ undefined,
|
||||
minArgumentCount, hasRestLikeParameter, hasLiteralTypes);
|
||||
minArgumentCount, flags);
|
||||
}
|
||||
return links.resolvedSignature;
|
||||
}
|
||||
|
@ -10255,8 +10256,8 @@ namespace ts {
|
|||
signature.unionSignatures ? getUnionType(map(signature.unionSignatures, getReturnTypeOfSignature), UnionReduction.Subtype) :
|
||||
getReturnTypeFromAnnotation(signature.declaration!) ||
|
||||
(nodeIsMissing((<FunctionLikeDeclaration>signature.declaration).body) ? anyType : getReturnTypeFromBody(<FunctionLikeDeclaration>signature.declaration));
|
||||
if (signature.isOptionalCall) {
|
||||
type = propagateOptionalTypeMarker(type, /*wasOptional*/ true);
|
||||
if (signatureIsOptionalCall(signature)) {
|
||||
type = addOptionalTypeMarker(type);
|
||||
}
|
||||
if (!popTypeResolution()) {
|
||||
if (signature.declaration) {
|
||||
|
@ -10316,7 +10317,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function tryGetRestTypeOfSignature(signature: Signature): Type | undefined {
|
||||
if (signature.hasRestParameter) {
|
||||
if (signatureHasRestParameter(signature)) {
|
||||
const sigRestType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
|
||||
const restType = isTupleType(sigRestType) ? getRestTypeOfTupleType(sigRestType) : sigRestType;
|
||||
return restType && getIndexTypeOfType(restType, IndexKind.Number);
|
||||
|
@ -10748,7 +10749,7 @@ namespace ts {
|
|||
/**
|
||||
* A JSdoc TypeReference may be to a value, but resolve it as a type anyway.
|
||||
* Note: If the value is imported from commonjs, it should really be an alias,
|
||||
* but this function fakes special-case code fakes alias resolution as well.
|
||||
* but this function's special-case code fakes alias resolution as well.
|
||||
*/
|
||||
function getTypeFromJSDocValueReference(node: NodeWithTypeArguments, symbol: Symbol): Type | undefined {
|
||||
const valueType = getTypeOfSymbol(symbol);
|
||||
|
@ -10760,7 +10761,7 @@ namespace ts {
|
|||
&& isCallExpression(decl.initializer)
|
||||
&& isRequireCall(decl.initializer, /*requireStringLiteralLikeArgument*/ true)
|
||||
&& valueType.symbol;
|
||||
if (isRequireAlias) {
|
||||
if (isRequireAlias || node.kind === SyntaxKind.ImportType) {
|
||||
typeType = getTypeReferenceType(node, valueType.symbol);
|
||||
}
|
||||
}
|
||||
|
@ -12898,8 +12899,7 @@ namespace ts {
|
|||
/*resolvedReturnType*/ undefined,
|
||||
/*resolvedTypePredicate*/ undefined,
|
||||
signature.minArgumentCount,
|
||||
signature.hasRestParameter,
|
||||
signature.hasLiteralTypes);
|
||||
signature.flags & SignatureFlags.PropagatingFlags);
|
||||
result.target = signature;
|
||||
result.mapper = mapper;
|
||||
return result;
|
||||
|
@ -13852,7 +13852,7 @@ namespace ts {
|
|||
*/
|
||||
function isAnySignature(s: Signature) {
|
||||
return !s.typeParameters && (!s.thisParameter || isTypeAny(getTypeOfParameter(s.thisParameter))) && s.parameters.length === 1 &&
|
||||
s.hasRestParameter && (getTypeOfParameter(s.parameters[0]) === anyArrayType || isTypeAny(getTypeOfParameter(s.parameters[0]))) &&
|
||||
signatureHasRestParameter(s) && (getTypeOfParameter(s.parameters[0]) === anyArrayType || isTypeAny(getTypeOfParameter(s.parameters[0]))) &&
|
||||
isTypeAny(getReturnTypeOfSignature(s));
|
||||
}
|
||||
|
||||
|
@ -16677,48 +16677,22 @@ namespace ts {
|
|||
return strictNullChecks ? getUnionType([type, optionalType]) : type;
|
||||
}
|
||||
|
||||
function isNotOptionalTypeMarker(type: Type) {
|
||||
return type !== optionalType;
|
||||
}
|
||||
|
||||
function removeOptionalTypeMarker(type: Type): Type {
|
||||
return strictNullChecks ? filterType(type, t => t !== optionalType) : type;
|
||||
return strictNullChecks ? filterType(type, isNotOptionalTypeMarker) : type;
|
||||
}
|
||||
|
||||
function propagateOptionalTypeMarker(type: Type, wasOptional: boolean) {
|
||||
return wasOptional ? addOptionalTypeMarker(type) : type;
|
||||
}
|
||||
|
||||
function createPooledOptionalTypeResult(isOptional: boolean, type: Type) {
|
||||
pooledOptionalTypeResult.isOptional = isOptional;
|
||||
pooledOptionalTypeResult.type = type;
|
||||
return pooledOptionalTypeResult;
|
||||
}
|
||||
|
||||
function checkOptionalExpression(
|
||||
parent: PropertyAccessExpression | QualifiedName | ElementAccessExpression | CallExpression,
|
||||
expression: Expression | QualifiedName,
|
||||
nullDiagnostic?: DiagnosticMessage,
|
||||
undefinedDiagnostic?: DiagnosticMessage,
|
||||
nullOrUndefinedDiagnostic?: DiagnosticMessage,
|
||||
) {
|
||||
let isOptional = false;
|
||||
let type = checkExpression(expression);
|
||||
if (isOptionalChain(parent)) {
|
||||
if (parent.questionDotToken) {
|
||||
// If we have a questionDotToken then we are an OptionalExpression and should remove `null` and
|
||||
// `undefined` from the type and add the optionalType to the result, if needed.
|
||||
isOptional = isNullableType(type);
|
||||
return createPooledOptionalTypeResult(isOptional, isOptional ? getNonNullableType(type) : type);
|
||||
}
|
||||
|
||||
// If we do not have a questionDotToken, then we are an OptionalChain and we remove the optionalType and
|
||||
// indicate whether we need to add optionalType back into the result.
|
||||
const nonOptionalType = removeOptionalTypeMarker(type);
|
||||
if (nonOptionalType !== type) {
|
||||
isOptional = true;
|
||||
type = nonOptionalType;
|
||||
}
|
||||
}
|
||||
|
||||
type = checkNonNullType(type, expression, nullDiagnostic, undefinedDiagnostic, nullOrUndefinedDiagnostic);
|
||||
return createPooledOptionalTypeResult(isOptional, type);
|
||||
function getOptionalExpressionType(exprType: Type, expression: Expression) {
|
||||
return isExpressionOfOptionalChainRoot(expression) ? getNonNullableType(exprType) :
|
||||
isOptionalChain(expression) ? removeOptionalTypeMarker(exprType) :
|
||||
exprType;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -17375,10 +17349,7 @@ namespace ts {
|
|||
// inferring a type parameter constraint. Instead, make a lower priority inference from
|
||||
// the full source to whatever remains in the target. For example, when inferring from
|
||||
// string to 'string | T', make a lower priority inference of string for T.
|
||||
const savePriority = priority;
|
||||
priority |= InferencePriority.NakedTypeVariable;
|
||||
inferFromTypes(source, target);
|
||||
priority = savePriority;
|
||||
inferWithPriority(source, target, InferencePriority.NakedTypeVariable);
|
||||
return;
|
||||
}
|
||||
source = getUnionType(sources);
|
||||
|
@ -17480,10 +17451,7 @@ namespace ts {
|
|||
else if ((isLiteralType(source) || source.flags & TypeFlags.String) && target.flags & TypeFlags.Index) {
|
||||
const empty = createEmptyObjectTypeFromStringLiteral(source);
|
||||
contravariant = !contravariant;
|
||||
const savePriority = priority;
|
||||
priority |= InferencePriority.LiteralKeyof;
|
||||
inferFromTypes(empty, (target as IndexType).type);
|
||||
priority = savePriority;
|
||||
inferWithPriority(empty, (target as IndexType).type, InferencePriority.LiteralKeyof);
|
||||
contravariant = !contravariant;
|
||||
}
|
||||
else if (source.flags & TypeFlags.IndexedAccess && target.flags & TypeFlags.IndexedAccess) {
|
||||
|
@ -17535,6 +17503,13 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function inferWithPriority(source: Type, target: Type, newPriority: InferencePriority) {
|
||||
const savePriority = priority;
|
||||
priority |= newPriority;
|
||||
inferFromTypes(source, target);
|
||||
priority = savePriority;
|
||||
}
|
||||
|
||||
function invokeOnce(source: Type, target: Type, action: (source: Type, target: Type) => void) {
|
||||
const key = source.id + "," + target.id;
|
||||
const status = visited && visited.get(key);
|
||||
|
@ -17602,6 +17577,18 @@ namespace ts {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
function getSingleTypeVariableFromIntersectionTypes(types: Type[]) {
|
||||
let typeVariable: Type | undefined;
|
||||
for (const type of types) {
|
||||
const t = type.flags & TypeFlags.Intersection && find((<IntersectionType>type).types, t => !!getInferenceInfoForType(t));
|
||||
if (!t || typeVariable && t !== typeVariable) {
|
||||
return undefined;
|
||||
}
|
||||
typeVariable = t;
|
||||
}
|
||||
return typeVariable;
|
||||
}
|
||||
|
||||
function inferToMultipleTypes(source: Type, targets: Type[], targetFlags: TypeFlags) {
|
||||
let typeVariableCount = 0;
|
||||
if (targetFlags & TypeFlags.Union) {
|
||||
|
@ -17629,6 +17616,16 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (typeVariableCount === 0) {
|
||||
// If every target is an intersection of types containing a single naked type variable,
|
||||
// make a lower priority inference to that type variable. This handles inferring from
|
||||
// 'A | B' to 'T & (X | Y)' where we want to infer 'A | B' for T.
|
||||
const intersectionTypeVariable = getSingleTypeVariableFromIntersectionTypes(targets);
|
||||
if (intersectionTypeVariable) {
|
||||
inferWithPriority(source, intersectionTypeVariable, InferencePriority.NakedTypeVariable);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// If the target has a single naked type variable and no inference circularities were
|
||||
// encountered above (meaning we explored the types fully), create a union of the source
|
||||
// types from which no inferences have been made so far and infer from that union to the
|
||||
|
@ -17659,14 +17656,11 @@ namespace ts {
|
|||
// we want to infer string for T, not Promise<string> | string. For intersection types
|
||||
// we only infer to single naked type variables.
|
||||
if (targetFlags & TypeFlags.Intersection ? typeVariableCount === 1 : typeVariableCount > 0) {
|
||||
const savePriority = priority;
|
||||
priority |= InferencePriority.NakedTypeVariable;
|
||||
for (const t of targets) {
|
||||
if (getInferenceInfoForType(t)) {
|
||||
inferFromTypes(source, t);
|
||||
inferWithPriority(source, t, InferencePriority.NakedTypeVariable);
|
||||
}
|
||||
}
|
||||
priority = savePriority;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17687,14 +17681,13 @@ namespace ts {
|
|||
if (inference && !inference.isFixed) {
|
||||
const inferredType = inferTypeForHomomorphicMappedType(source, target, <IndexType>constraintType);
|
||||
if (inferredType) {
|
||||
const savePriority = priority;
|
||||
// We assign a lower priority to inferences made from types containing non-inferrable
|
||||
// types because we may only have a partial result (i.e. we may have failed to make
|
||||
// reverse inferences for some properties).
|
||||
priority |= getObjectFlags(source) & ObjectFlags.NonInferrableType ?
|
||||
InferencePriority.PartialHomomorphicMappedType : InferencePriority.HomomorphicMappedType;
|
||||
inferFromTypes(inferredType, inference.typeParameter);
|
||||
priority = savePriority;
|
||||
inferWithPriority(inferredType, inference.typeParameter,
|
||||
getObjectFlags(source) & ObjectFlags.NonInferrableType ?
|
||||
InferencePriority.PartialHomomorphicMappedType :
|
||||
InferencePriority.HomomorphicMappedType);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -17702,10 +17695,7 @@ namespace ts {
|
|||
if (constraintType.flags & TypeFlags.TypeParameter) {
|
||||
// We're inferring from some source type S to a mapped type { [P in K]: X }, where K is a type
|
||||
// parameter. First infer from 'keyof S' to K.
|
||||
const savePriority = priority;
|
||||
priority |= InferencePriority.MappedTypeConstraint;
|
||||
inferFromTypes(getIndexType(source), constraintType);
|
||||
priority = savePriority;
|
||||
inferWithPriority(getIndexType(source), constraintType, InferencePriority.MappedTypeConstraint);
|
||||
// If K is constrained to a type C, also infer to C. Thus, for a mapped type { [P in K]: X },
|
||||
// where K extends keyof T, we make the same inferences as for a homomorphic mapped type
|
||||
// { [P in keyof T]: X }. This enables us to make meaningful inferences when the target is a
|
||||
|
@ -18762,9 +18752,21 @@ namespace ts {
|
|||
// expressions are potential type predicate function calls. In order to avoid triggering
|
||||
// circularities in control flow analysis, we use getTypeOfDottedName when resolving the call
|
||||
// target expression of an assertion.
|
||||
const funcType = node.parent.kind === SyntaxKind.ExpressionStatement ? getTypeOfDottedName(node.expression, /*diagnostic*/ undefined) :
|
||||
node.expression.kind !== SyntaxKind.SuperKeyword ? checkOptionalExpression(node, node.expression).type :
|
||||
undefined;
|
||||
let funcType: Type | undefined;
|
||||
if (node.parent.kind === SyntaxKind.ExpressionStatement) {
|
||||
funcType = getTypeOfDottedName(node.expression, /*diagnostic*/ undefined);
|
||||
}
|
||||
else if (node.expression.kind !== SyntaxKind.SuperKeyword) {
|
||||
if (isOptionalChain(node)) {
|
||||
funcType = checkNonNullType(
|
||||
getOptionalExpressionType(checkExpression(node.expression), node.expression),
|
||||
node.expression
|
||||
);
|
||||
}
|
||||
else {
|
||||
funcType = checkNonNullExpression(node.expression);
|
||||
}
|
||||
}
|
||||
const signatures = getSignaturesOfType(funcType && getApparentType(funcType) || unknownType, SignatureKind.Call);
|
||||
const candidate = signatures.length === 1 && !signatures[0].typeParameters ? signatures[0] :
|
||||
some(signatures, hasTypePredicateOrNeverReturnType) ? getResolvedSignature(node) :
|
||||
|
@ -18779,6 +18781,14 @@ namespace ts {
|
|||
signature.declaration && (getReturnTypeFromAnnotation(signature.declaration) || unknownType).flags & TypeFlags.Never);
|
||||
}
|
||||
|
||||
function getTypePredicateArgument(predicate: TypePredicate, callExpression: CallExpression) {
|
||||
if (predicate.kind === TypePredicateKind.Identifier || predicate.kind === TypePredicateKind.AssertsIdentifier) {
|
||||
return callExpression.arguments[predicate.parameterIndex];
|
||||
}
|
||||
const invokedExpression = skipParentheses(callExpression.expression);
|
||||
return isAccessExpression(invokedExpression) ? skipParentheses(invokedExpression.expression) : undefined;
|
||||
}
|
||||
|
||||
function reportFlowControlError(node: Node) {
|
||||
const block = <Block | ModuleBlock | SourceFile>findAncestor(node, isFunctionOrModuleBlock);
|
||||
const sourceFile = getSourceFileOfNode(node);
|
||||
|
@ -19167,20 +19177,30 @@ namespace ts {
|
|||
if (isMatchingReference(reference, expr)) {
|
||||
type = narrowTypeBySwitchOnDiscriminant(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd);
|
||||
}
|
||||
else if (isMatchingReferenceDiscriminant(expr, type)) {
|
||||
type = narrowTypeByDiscriminant(
|
||||
type,
|
||||
expr as AccessExpression,
|
||||
t => narrowTypeBySwitchOnDiscriminant(t, flow.switchStatement, flow.clauseStart, flow.clauseEnd));
|
||||
}
|
||||
else if (expr.kind === SyntaxKind.TypeOfExpression && isMatchingReference(reference, (expr as TypeOfExpression).expression)) {
|
||||
type = narrowBySwitchOnTypeOf(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd);
|
||||
}
|
||||
else if (containsMatchingReferenceDiscriminant(reference, expr)) {
|
||||
type = declaredType;
|
||||
}
|
||||
else if (flow.clauseStart === flow.clauseEnd && isExhaustiveSwitchStatement(flow.switchStatement)) {
|
||||
return unreachableNeverType;
|
||||
else {
|
||||
if (strictNullChecks) {
|
||||
if (optionalChainContainsReference(expr, reference)) {
|
||||
type = narrowTypeBySwitchOptionalChainContainment(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd,
|
||||
t => !(t.flags & (TypeFlags.Undefined | TypeFlags.Never)));
|
||||
}
|
||||
else if (expr.kind === SyntaxKind.TypeOfExpression && optionalChainContainsReference((expr as TypeOfExpression).expression, reference)) {
|
||||
type = narrowTypeBySwitchOptionalChainContainment(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd,
|
||||
t => !(t.flags & TypeFlags.Never || t.flags & TypeFlags.StringLiteral && (<StringLiteralType>t).value === "undefined"));
|
||||
}
|
||||
}
|
||||
if (isMatchingReferenceDiscriminant(expr, type)) {
|
||||
type = narrowTypeByDiscriminant(type, expr as AccessExpression,
|
||||
t => narrowTypeBySwitchOnDiscriminant(t, flow.switchStatement, flow.clauseStart, flow.clauseEnd));
|
||||
}
|
||||
else if (containsMatchingReferenceDiscriminant(reference, expr)) {
|
||||
type = declaredType;
|
||||
}
|
||||
else if (flow.clauseStart === flow.clauseEnd && isExhaustiveSwitchStatement(flow.switchStatement)) {
|
||||
return unreachableNeverType;
|
||||
}
|
||||
}
|
||||
return createFlowType(type, isIncomplete(flowType));
|
||||
}
|
||||
|
@ -19325,6 +19345,9 @@ namespace ts {
|
|||
if (isMatchingReference(reference, expr)) {
|
||||
return getTypeWithFacts(type, assumeTrue ? TypeFacts.Truthy : TypeFacts.Falsy);
|
||||
}
|
||||
if (strictNullChecks && assumeTrue && optionalChainContainsReference(expr, reference)) {
|
||||
type = getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull);
|
||||
}
|
||||
if (isMatchingReferenceDiscriminant(expr, declaredType)) {
|
||||
return narrowTypeByDiscriminant(type, <AccessExpression>expr, t => getTypeWithFacts(t, assumeTrue ? TypeFacts.Truthy : TypeFacts.Falsy));
|
||||
}
|
||||
|
@ -19376,12 +19399,12 @@ namespace ts {
|
|||
if (isMatchingReference(reference, right)) {
|
||||
return narrowTypeByEquality(type, operator, left, assumeTrue);
|
||||
}
|
||||
if (assumeTrue && strictNullChecks) {
|
||||
if (strictNullChecks) {
|
||||
if (optionalChainContainsReference(left, reference)) {
|
||||
type = narrowTypeByOptionalChainContainment(type, operator, right);
|
||||
type = narrowTypeByOptionalChainContainment(type, operator, right, assumeTrue);
|
||||
}
|
||||
else if (optionalChainContainsReference(right, reference)) {
|
||||
type = narrowTypeByOptionalChainContainment(type, operator, left);
|
||||
type = narrowTypeByOptionalChainContainment(type, operator, left, assumeTrue);
|
||||
}
|
||||
}
|
||||
if (isMatchingReferenceDiscriminant(left, declaredType)) {
|
||||
|
@ -19408,16 +19431,14 @@ namespace ts {
|
|||
return type;
|
||||
}
|
||||
|
||||
function narrowTypeByOptionalChainContainment(type: Type, operator: SyntaxKind, value: Expression): Type {
|
||||
// We are in the true branch of obj?.foo === value or obj?.foo !== value. We remove undefined and null from
|
||||
function narrowTypeByOptionalChainContainment(type: Type, operator: SyntaxKind, value: Expression, assumeTrue: boolean): Type {
|
||||
// We are in a branch of obj?.foo === value or obj?.foo !== value. We remove undefined and null from
|
||||
// the type of obj if (a) the operator is === and the type of value doesn't include undefined or (b) the
|
||||
// operator is !== and the type of value is undefined.
|
||||
const valueType = getTypeOfExpression(value);
|
||||
return operator === SyntaxKind.EqualsEqualsToken && !(getTypeFacts(valueType) & TypeFacts.EQUndefinedOrNull) ||
|
||||
operator === SyntaxKind.EqualsEqualsEqualsToken && !(getTypeFacts(valueType) & TypeFacts.EQUndefined) ||
|
||||
operator === SyntaxKind.ExclamationEqualsToken && valueType.flags & TypeFlags.Nullable ||
|
||||
operator === SyntaxKind.ExclamationEqualsEqualsToken && valueType.flags & TypeFlags.Undefined ?
|
||||
getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type;
|
||||
const effectiveTrue = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.EqualsEqualsEqualsToken ? assumeTrue : !assumeTrue;
|
||||
const doubleEquals = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsToken;
|
||||
const valueNonNullish = !(getTypeFacts(getTypeOfExpression(value)) & (doubleEquals ? TypeFacts.EQUndefinedOrNull : TypeFacts.EQUndefined));
|
||||
return effectiveTrue === valueNonNullish ? getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type;
|
||||
}
|
||||
|
||||
function narrowTypeByEquality(type: Type, operator: SyntaxKind, value: Expression, assumeTrue: boolean): Type {
|
||||
|
@ -19468,10 +19489,12 @@ namespace ts {
|
|||
|
||||
function narrowTypeByTypeof(type: Type, typeOfExpr: TypeOfExpression, operator: SyntaxKind, literal: LiteralExpression, assumeTrue: boolean): Type {
|
||||
// We have '==', '!=', '===', or !==' operator with 'typeof xxx' and string literal operands
|
||||
if (operator === SyntaxKind.ExclamationEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) {
|
||||
assumeTrue = !assumeTrue;
|
||||
}
|
||||
const target = getReferenceCandidate(typeOfExpr.expression);
|
||||
if (!isMatchingReference(reference, target)) {
|
||||
if (assumeTrue && (operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.EqualsEqualsEqualsToken) &&
|
||||
strictNullChecks && optionalChainContainsReference(target, reference)) {
|
||||
if (strictNullChecks && optionalChainContainsReference(target, reference) && assumeTrue === (literal.text !== "undefined")) {
|
||||
return getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull);
|
||||
}
|
||||
// For a reference of the form 'x.y', a 'typeof x === ...' type guard resets the
|
||||
|
@ -19481,9 +19504,6 @@ namespace ts {
|
|||
}
|
||||
return type;
|
||||
}
|
||||
if (operator === SyntaxKind.ExclamationEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) {
|
||||
assumeTrue = !assumeTrue;
|
||||
}
|
||||
if (type.flags & TypeFlags.Any && literal.text === "function") {
|
||||
return type;
|
||||
}
|
||||
|
@ -19518,6 +19538,11 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function narrowTypeBySwitchOptionalChainContainment(type: Type, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number, clauseCheck: (type: Type) => boolean) {
|
||||
const everyClauseChecks = clauseStart !== clauseEnd && every(getSwitchClauseTypes(switchStatement).slice(clauseStart, clauseEnd), clauseCheck);
|
||||
return everyClauseChecks ? getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type;
|
||||
}
|
||||
|
||||
function narrowTypeBySwitchOnDiscriminant(type: Type, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number) {
|
||||
// We only narrow if all case expressions specify
|
||||
// values with unit types, except for the case where
|
||||
|
@ -19738,32 +19763,21 @@ namespace ts {
|
|||
|
||||
function narrowTypeByTypePredicate(type: Type, predicate: TypePredicate, callExpression: CallExpression, assumeTrue: boolean): Type {
|
||||
// Don't narrow from 'any' if the predicate type is exactly 'Object' or 'Function'
|
||||
if (isTypeAny(type) && (predicate.type === globalObjectType || predicate.type === globalFunctionType)) {
|
||||
return type;
|
||||
}
|
||||
if (predicate.kind === TypePredicateKind.Identifier || predicate.kind === TypePredicateKind.AssertsIdentifier) {
|
||||
const predicateArgument = callExpression.arguments[predicate.parameterIndex];
|
||||
if (predicateArgument && predicate.type) {
|
||||
if (predicate.type && !(isTypeAny(type) && (predicate.type === globalObjectType || predicate.type === globalFunctionType))) {
|
||||
const predicateArgument = getTypePredicateArgument(predicate, callExpression);
|
||||
if (predicateArgument) {
|
||||
if (isMatchingReference(reference, predicateArgument)) {
|
||||
return getNarrowedType(type, predicate.type, assumeTrue, isTypeSubtypeOf);
|
||||
}
|
||||
if (strictNullChecks && assumeTrue && optionalChainContainsReference(predicateArgument, reference) &&
|
||||
!(getTypeFacts(predicate.type) & TypeFacts.EQUndefined)) {
|
||||
return getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull);
|
||||
}
|
||||
if (containsMatchingReference(reference, predicateArgument)) {
|
||||
return declaredType;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
const invokedExpression = skipParentheses(callExpression.expression);
|
||||
if (isAccessExpression(invokedExpression) && predicate.type) {
|
||||
const possibleReference = skipParentheses(invokedExpression.expression);
|
||||
if (isMatchingReference(reference, possibleReference)) {
|
||||
return getNarrowedType(type, predicate.type, assumeTrue, isTypeSubtypeOf);
|
||||
}
|
||||
if (containsMatchingReference(reference, possibleReference)) {
|
||||
return declaredType;
|
||||
}
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
@ -19771,7 +19785,7 @@ namespace ts {
|
|||
// will be a subtype or the same type as the argument.
|
||||
function narrowType(type: Type, expr: Expression, assumeTrue: boolean): Type {
|
||||
// for `a?.b`, we emulate a synthetic `a !== null && a !== undefined` condition for `a`
|
||||
if (isOptionalChainRoot(expr.parent) ||
|
||||
if (isExpressionOfOptionalChainRoot(expr) ||
|
||||
isBinaryExpression(expr.parent) && expr.parent.operatorToken.kind === SyntaxKind.QuestionQuestionToken && expr.parent.left === expr) {
|
||||
return narrowTypeByOptionality(type, expr, assumeTrue);
|
||||
}
|
||||
|
@ -22673,19 +22687,8 @@ namespace ts {
|
|||
return !!forEachProperty(symbol, prop => !(prop.flags & SymbolFlags.Method));
|
||||
}
|
||||
|
||||
function checkNonNullExpression(
|
||||
node: Expression | QualifiedName,
|
||||
nullDiagnostic?: DiagnosticMessage,
|
||||
undefinedDiagnostic?: DiagnosticMessage,
|
||||
nullOrUndefinedDiagnostic?: DiagnosticMessage,
|
||||
) {
|
||||
return checkNonNullType(
|
||||
checkExpression(node),
|
||||
node,
|
||||
nullDiagnostic,
|
||||
undefinedDiagnostic,
|
||||
nullOrUndefinedDiagnostic
|
||||
);
|
||||
function checkNonNullExpression(node: Expression | QualifiedName) {
|
||||
return checkNonNullType(checkExpression(node), node);
|
||||
}
|
||||
|
||||
function isNullableType(type: Type) {
|
||||
|
@ -22696,12 +22699,26 @@ namespace ts {
|
|||
return isNullableType(type) ? getNonNullableType(type) : type;
|
||||
}
|
||||
|
||||
function checkNonNullType(
|
||||
function reportObjectPossiblyNullOrUndefinedError(node: Node, flags: TypeFlags) {
|
||||
error(node, flags & TypeFlags.Undefined ? flags & TypeFlags.Null ?
|
||||
Diagnostics.Object_is_possibly_null_or_undefined :
|
||||
Diagnostics.Object_is_possibly_undefined :
|
||||
Diagnostics.Object_is_possibly_null
|
||||
);
|
||||
}
|
||||
|
||||
function reportCannotInvokePossiblyNullOrUndefinedError(node: Node, flags: TypeFlags) {
|
||||
error(node, flags & TypeFlags.Undefined ? flags & TypeFlags.Null ?
|
||||
Diagnostics.Cannot_invoke_an_object_which_is_possibly_null_or_undefined :
|
||||
Diagnostics.Cannot_invoke_an_object_which_is_possibly_undefined :
|
||||
Diagnostics.Cannot_invoke_an_object_which_is_possibly_null
|
||||
);
|
||||
}
|
||||
|
||||
function checkNonNullTypeWithReporter(
|
||||
type: Type,
|
||||
node: Node,
|
||||
nullDiagnostic?: DiagnosticMessage,
|
||||
undefinedDiagnostic?: DiagnosticMessage,
|
||||
nullOrUndefinedDiagnostic?: DiagnosticMessage
|
||||
reportError: (node: Node, kind: TypeFlags) => void
|
||||
): Type {
|
||||
if (strictNullChecks && type.flags & TypeFlags.Unknown) {
|
||||
error(node, Diagnostics.Object_is_of_type_unknown);
|
||||
|
@ -22709,17 +22726,17 @@ namespace ts {
|
|||
}
|
||||
const kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & TypeFlags.Nullable;
|
||||
if (kind) {
|
||||
error(node, kind & TypeFlags.Undefined ? kind & TypeFlags.Null ?
|
||||
(nullOrUndefinedDiagnostic || Diagnostics.Object_is_possibly_null_or_undefined) :
|
||||
(undefinedDiagnostic || Diagnostics.Object_is_possibly_undefined) :
|
||||
(nullDiagnostic || Diagnostics.Object_is_possibly_null)
|
||||
);
|
||||
reportError(node, kind);
|
||||
const t = getNonNullableType(type);
|
||||
return t.flags & (TypeFlags.Nullable | TypeFlags.Never) ? errorType : t;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function checkNonNullType(type: Type, node: Node) {
|
||||
return checkNonNullTypeWithReporter(type, node, reportObjectPossiblyNullOrUndefinedError);
|
||||
}
|
||||
|
||||
function checkNonNullNonVoidType(type: Type, node: Node): Type {
|
||||
const nonNullType = checkNonNullType(type, node);
|
||||
if (nonNullType !== errorType && nonNullType.flags & TypeFlags.Void) {
|
||||
|
@ -22729,11 +22746,18 @@ namespace ts {
|
|||
}
|
||||
|
||||
function checkPropertyAccessExpression(node: PropertyAccessExpression) {
|
||||
return checkPropertyAccessExpressionOrQualifiedName(node, node.expression, node.name);
|
||||
return node.flags & NodeFlags.OptionalChain ? checkPropertyAccessChain(node as PropertyAccessChain) :
|
||||
checkPropertyAccessExpressionOrQualifiedName(node, node.expression, checkNonNullExpression(node.expression), node.name);
|
||||
}
|
||||
|
||||
function checkPropertyAccessChain(node: PropertyAccessChain) {
|
||||
const leftType = checkExpression(node.expression);
|
||||
const nonOptionalType = getOptionalExpressionType(leftType, node.expression);
|
||||
return propagateOptionalTypeMarker(checkPropertyAccessExpressionOrQualifiedName(node, node.expression, checkNonNullType(nonOptionalType, node.expression), node.name), nonOptionalType !== leftType);
|
||||
}
|
||||
|
||||
function checkQualifiedName(node: QualifiedName) {
|
||||
return checkPropertyAccessExpressionOrQualifiedName(node, node.left, node.right);
|
||||
return checkPropertyAccessExpressionOrQualifiedName(node, node.left, checkNonNullExpression(node.left), node.right);
|
||||
}
|
||||
|
||||
function isMethodAccessForCall(node: Node) {
|
||||
|
@ -22743,8 +22767,7 @@ namespace ts {
|
|||
return isCallOrNewExpression(node.parent) && node.parent.expression === node;
|
||||
}
|
||||
|
||||
function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, right: Identifier) {
|
||||
const { isOptional, type: leftType } = checkOptionalExpression(node, left);
|
||||
function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, leftType: Type, right: Identifier) {
|
||||
const parentSymbol = getNodeLinks(left).resolvedSymbol;
|
||||
const assignmentKind = getAssignmentTargetKind(node);
|
||||
const apparentType = getApparentType(assignmentKind !== AssignmentKind.None || isMethodAccessForCall(node) ? getWidenedType(leftType) : leftType);
|
||||
|
@ -22798,7 +22821,7 @@ namespace ts {
|
|||
}
|
||||
propType = getConstraintForLocation(getTypeOfSymbol(prop), node);
|
||||
}
|
||||
return propagateOptionalTypeMarker(getFlowTypeOfAccessExpression(node, prop, propType, right), isOptional);
|
||||
return getFlowTypeOfAccessExpression(node, prop, propType, right);
|
||||
}
|
||||
|
||||
function getFlowTypeOfAccessExpression(node: ElementAccessExpression | PropertyAccessExpression | QualifiedName, prop: Symbol | undefined, propType: Type, errorNode: Node) {
|
||||
|
@ -23155,7 +23178,17 @@ namespace ts {
|
|||
}
|
||||
|
||||
function checkIndexedAccess(node: ElementAccessExpression): Type {
|
||||
const { isOptional, type: exprType } = checkOptionalExpression(node, node.expression);
|
||||
return node.flags & NodeFlags.OptionalChain ? checkElementAccessChain(node as ElementAccessChain) :
|
||||
checkElementAccessExpression(node, checkNonNullExpression(node.expression));
|
||||
}
|
||||
|
||||
function checkElementAccessChain(node: ElementAccessChain) {
|
||||
const exprType = checkExpression(node.expression);
|
||||
const nonOptionalType = getOptionalExpressionType(exprType, node.expression);
|
||||
return propagateOptionalTypeMarker(checkElementAccessExpression(node, checkNonNullType(nonOptionalType, node.expression)), nonOptionalType !== exprType);
|
||||
}
|
||||
|
||||
function checkElementAccessExpression(node: ElementAccessExpression, exprType: Type): Type {
|
||||
const objectType = getAssignmentTargetKind(node) !== AssignmentKind.None || isMethodAccessForCall(node) ? getWidenedType(exprType) : exprType;
|
||||
const indexExpression = node.argumentExpression;
|
||||
const indexType = checkExpression(indexExpression);
|
||||
|
@ -23174,7 +23207,7 @@ namespace ts {
|
|||
AccessFlags.Writing | (isGenericObjectType(objectType) && !isThisTypeParameter(objectType) ? AccessFlags.NoIndexSignatures : 0) :
|
||||
AccessFlags.None;
|
||||
const indexedAccessType = getIndexedAccessTypeOrUndefined(objectType, effectiveIndexType, node, accessFlags) || errorType;
|
||||
return propagateOptionalTypeMarker(checkIndexedAccessIndexType(getFlowTypeOfAccessExpression(node, indexedAccessType.symbol, indexedAccessType, indexExpression), node), isOptional);
|
||||
return checkIndexedAccessIndexType(getFlowTypeOfAccessExpression(node, indexedAccessType.symbol, indexedAccessType, indexExpression), node);
|
||||
}
|
||||
|
||||
function checkThatExpressionIsProperSymbolReference(expression: Expression, expressionType: Type, reportError: boolean): boolean {
|
||||
|
@ -23287,7 +23320,7 @@ namespace ts {
|
|||
|
||||
// specialized signatures always need to be placed before non-specialized signatures regardless
|
||||
// of the cutoff position; see GH#1133
|
||||
if (signature.hasLiteralTypes) {
|
||||
if (signatureHasLiteralTypes(signature)) {
|
||||
specializedIndex++;
|
||||
spliceIndex = specializedIndex;
|
||||
// The cutoff index always needs to be greater than or equal to the specialized signature index
|
||||
|
@ -23299,7 +23332,7 @@ namespace ts {
|
|||
spliceIndex = index;
|
||||
}
|
||||
|
||||
result.splice(spliceIndex, 0, isOptionalCall ? createOptionalCallSignature(signature) : signature);
|
||||
result.splice(spliceIndex, 0, isOptionalCall ? getOptionalCallSignature(signature) : signature);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24257,17 +24290,21 @@ namespace ts {
|
|||
const { min: minArgumentCount, max: maxNonRestParam } = minAndMax(candidates, getNumNonRestParameters);
|
||||
const parameters: Symbol[] = [];
|
||||
for (let i = 0; i < maxNonRestParam; i++) {
|
||||
const symbols = mapDefined(candidates, ({ parameters, hasRestParameter }) => hasRestParameter ?
|
||||
i < parameters.length - 1 ? parameters[i] : last(parameters) :
|
||||
i < parameters.length ? parameters[i] : undefined);
|
||||
const symbols = mapDefined(candidates, s => signatureHasRestParameter(s) ?
|
||||
i < s.parameters.length - 1 ? s.parameters[i] : last(s.parameters) :
|
||||
i < s.parameters.length ? s.parameters[i] : undefined);
|
||||
Debug.assert(symbols.length !== 0);
|
||||
parameters.push(createCombinedSymbolFromTypes(symbols, mapDefined(candidates, candidate => tryGetTypeAtPosition(candidate, i))));
|
||||
}
|
||||
const restParameterSymbols = mapDefined(candidates, c => c.hasRestParameter ? last(c.parameters) : undefined);
|
||||
const hasRestParameter = restParameterSymbols.length !== 0;
|
||||
if (hasRestParameter) {
|
||||
const restParameterSymbols = mapDefined(candidates, c => signatureHasRestParameter(c) ? last(c.parameters) : undefined);
|
||||
let flags = SignatureFlags.None;
|
||||
if (restParameterSymbols.length !== 0) {
|
||||
const type = createArrayType(getUnionType(mapDefined(candidates, tryGetRestTypeOfSignature), UnionReduction.Subtype));
|
||||
parameters.push(createCombinedSymbolForOverloadFailure(restParameterSymbols, type));
|
||||
flags |= SignatureFlags.HasRestParameter;
|
||||
}
|
||||
if (candidates.some(signatureHasLiteralTypes)) {
|
||||
flags |= SignatureFlags.HasLiteralTypes;
|
||||
}
|
||||
return createSignature(
|
||||
candidates[0].declaration,
|
||||
|
@ -24277,13 +24314,12 @@ namespace ts {
|
|||
/*resolvedReturnType*/ getIntersectionType(candidates.map(getReturnTypeOfSignature)),
|
||||
/*typePredicate*/ undefined,
|
||||
minArgumentCount,
|
||||
hasRestParameter,
|
||||
/*hasLiteralTypes*/ candidates.some(c => c.hasLiteralTypes));
|
||||
flags);
|
||||
}
|
||||
|
||||
function getNumNonRestParameters(signature: Signature): number {
|
||||
const numParams = signature.parameters.length;
|
||||
return signature.hasRestParameter ? numParams - 1 : numParams;
|
||||
return signatureHasRestParameter(signature) ? numParams - 1 : numParams;
|
||||
}
|
||||
|
||||
function createCombinedSymbolFromTypes(sources: readonly Symbol[], types: Type[]): Symbol {
|
||||
|
@ -24374,12 +24410,20 @@ namespace ts {
|
|||
return resolveUntypedCall(node);
|
||||
}
|
||||
|
||||
const { isOptional, type: funcType } = checkOptionalExpression(
|
||||
node,
|
||||
let isOptional: boolean;
|
||||
let funcType = checkExpression(node.expression);
|
||||
if (isCallChain(node)) {
|
||||
const nonOptionalType = getOptionalExpressionType(funcType, node.expression);
|
||||
isOptional = nonOptionalType !== funcType;
|
||||
funcType = nonOptionalType;
|
||||
}
|
||||
else {
|
||||
isOptional = false;
|
||||
}
|
||||
funcType = checkNonNullTypeWithReporter(
|
||||
funcType,
|
||||
node.expression,
|
||||
Diagnostics.Cannot_invoke_an_object_which_is_possibly_null,
|
||||
Diagnostics.Cannot_invoke_an_object_which_is_possibly_undefined,
|
||||
Diagnostics.Cannot_invoke_an_object_which_is_possibly_null_or_undefined
|
||||
reportCannotInvokePossiblyNullOrUndefinedError
|
||||
);
|
||||
|
||||
if (funcType === silentNeverType) {
|
||||
|
@ -24833,8 +24877,7 @@ namespace ts {
|
|||
typeSymbol ? getDeclaredTypeOfSymbol(typeSymbol) : errorType,
|
||||
/*returnTypePredicate*/ undefined,
|
||||
1,
|
||||
/*hasRestparameter*/ false,
|
||||
/*hasLiteralTypes*/ false
|
||||
SignatureFlags.None
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -24873,7 +24916,7 @@ namespace ts {
|
|||
function isPotentiallyUncalledDecorator(decorator: Decorator, signatures: readonly Signature[]) {
|
||||
return signatures.length && every(signatures, signature =>
|
||||
signature.minArgumentCount === 0 &&
|
||||
!signature.hasRestParameter &&
|
||||
!signatureHasRestParameter(signature) &&
|
||||
signature.parameters.length < getDecoratorArgumentCount(decorator, signature));
|
||||
}
|
||||
|
||||
|
@ -24947,7 +24990,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function mergeJSSymbols(target: Symbol, source: Symbol | undefined) {
|
||||
if (source && (hasEntries(source.exports) || hasEntries(source.members))) {
|
||||
if (source) {
|
||||
const links = getSymbolLinks(source);
|
||||
if (!links.inferredClassSymbol || !links.inferredClassSymbol.has("" + getSymbolId(target))) {
|
||||
const inferred = isTransientSymbol(target) ? target : cloneSymbol(target) as TransientSymbol;
|
||||
|
@ -25289,7 +25332,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function getParameterNameAtPosition(signature: Signature, pos: number) {
|
||||
const paramCount = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
|
||||
const paramCount = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0);
|
||||
if (pos < paramCount) {
|
||||
return signature.parameters[pos].escapedName;
|
||||
}
|
||||
|
@ -25308,11 +25351,11 @@ namespace ts {
|
|||
}
|
||||
|
||||
function tryGetTypeAtPosition(signature: Signature, pos: number): Type | undefined {
|
||||
const paramCount = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
|
||||
const paramCount = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0);
|
||||
if (pos < paramCount) {
|
||||
return getTypeOfParameter(signature.parameters[pos]);
|
||||
}
|
||||
if (signature.hasRestParameter) {
|
||||
if (signatureHasRestParameter(signature)) {
|
||||
// We want to return the value undefined for an out of bounds parameter position,
|
||||
// so we need to check bounds here before calling getIndexedAccessType (which
|
||||
// otherwise would return the type 'undefined').
|
||||
|
@ -25349,7 +25392,7 @@ namespace ts {
|
|||
|
||||
function getParameterCount(signature: Signature) {
|
||||
const length = signature.parameters.length;
|
||||
if (signature.hasRestParameter) {
|
||||
if (signatureHasRestParameter(signature)) {
|
||||
const restType = getTypeOfSymbol(signature.parameters[length - 1]);
|
||||
if (isTupleType(restType)) {
|
||||
return length + getTypeArguments(restType).length - 1;
|
||||
|
@ -25359,7 +25402,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function getMinArgumentCount(signature: Signature) {
|
||||
if (signature.hasRestParameter) {
|
||||
if (signatureHasRestParameter(signature)) {
|
||||
const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
|
||||
if (isTupleType(restType)) {
|
||||
const minLength = restType.target.minLength;
|
||||
|
@ -25372,7 +25415,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function hasEffectiveRestParameter(signature: Signature) {
|
||||
if (signature.hasRestParameter) {
|
||||
if (signatureHasRestParameter(signature)) {
|
||||
const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
|
||||
return !isTupleType(restType) || restType.target.hasRestElement;
|
||||
}
|
||||
|
@ -25380,7 +25423,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function getEffectiveRestType(signature: Signature) {
|
||||
if (signature.hasRestParameter) {
|
||||
if (signatureHasRestParameter(signature)) {
|
||||
const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
|
||||
return isTupleType(restType) ? getRestArrayTypeOfTupleType(restType) : restType;
|
||||
}
|
||||
|
@ -25401,7 +25444,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function inferFromAnnotatedParameters(signature: Signature, context: Signature, inferenceContext: InferenceContext) {
|
||||
const len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
|
||||
const len = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0);
|
||||
for (let i = 0; i < len; i++) {
|
||||
const declaration = <ParameterDeclaration>signature.parameters[i].valueDeclaration;
|
||||
if (declaration.type) {
|
||||
|
@ -25435,7 +25478,7 @@ namespace ts {
|
|||
assignTypeToParameterAndFixTypeParameters(signature.thisParameter!, getTypeOfSymbol(context.thisParameter));
|
||||
}
|
||||
}
|
||||
const len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
|
||||
const len = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0);
|
||||
for (let i = 0; i < len; i++) {
|
||||
const parameter = signature.parameters[i];
|
||||
if (!getEffectiveTypeAnnotationNode(<ParameterDeclaration>parameter.valueDeclaration)) {
|
||||
|
@ -25443,7 +25486,7 @@ namespace ts {
|
|||
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType);
|
||||
}
|
||||
}
|
||||
if (signature.hasRestParameter) {
|
||||
if (signatureHasRestParameter(signature)) {
|
||||
// parameter might be a transient symbol generated by use of `arguments` in the function body.
|
||||
const parameter = last(signature.parameters);
|
||||
if (isTransientSymbol(parameter) || !getEffectiveTypeAnnotationNode(<ParameterDeclaration>parameter.valueDeclaration)) {
|
||||
|
@ -25881,7 +25924,7 @@ namespace ts {
|
|||
return links.contextFreeType;
|
||||
}
|
||||
const returnType = getReturnTypeFromBody(node, checkMode);
|
||||
const returnOnlySignature = createSignature(undefined, undefined, undefined, emptyArray, returnType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
|
||||
const returnOnlySignature = createSignature(undefined, undefined, undefined, emptyArray, returnType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None);
|
||||
const returnOnlyType = createAnonymousType(node.symbol, emptySymbols, [returnOnlySignature], emptyArray, undefined, undefined);
|
||||
returnOnlyType.objectFlags |= ObjectFlags.NonInferrableType;
|
||||
return links.contextFreeType = returnOnlyType;
|
||||
|
@ -27346,7 +27389,18 @@ namespace ts {
|
|||
// Optimize for the common case of a call to a function with a single non-generic call
|
||||
// signature where we can just fetch the return type without checking the arguments.
|
||||
if (isCallExpression(expr) && expr.expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(expr, /*checkArgumentIsStringLiteralLike*/ true) && !isSymbolOrSymbolForCall(expr)) {
|
||||
const { isOptional, type: funcType } = checkOptionalExpression(expr, expr.expression);
|
||||
let isOptional: boolean;
|
||||
let funcType: Type;
|
||||
if (isCallChain(expr)) {
|
||||
funcType = checkExpression(expr.expression);
|
||||
const nonOptionalType = getOptionalExpressionType(funcType, expr.expression);
|
||||
isOptional = funcType !== nonOptionalType;
|
||||
funcType = checkNonNullType(nonOptionalType, expr.expression);
|
||||
}
|
||||
else {
|
||||
isOptional = false;
|
||||
funcType = checkNonNullExpression(expr.expression);
|
||||
}
|
||||
const signature = getSingleCallSignature(funcType);
|
||||
if (signature && !signature.typeParameters) {
|
||||
return propagateOptionalTypeMarker(getReturnTypeOfSignature(signature), isOptional);
|
||||
|
@ -27621,7 +27675,7 @@ namespace ts {
|
|||
}
|
||||
else {
|
||||
if (typePredicate.parameterIndex >= 0) {
|
||||
if (signature.hasRestParameter && typePredicate.parameterIndex === signature.parameters.length - 1) {
|
||||
if (signatureHasRestParameter(signature) && typePredicate.parameterIndex === signature.parameters.length - 1) {
|
||||
error(parameterName, Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter);
|
||||
}
|
||||
else {
|
||||
|
@ -36053,4 +36107,16 @@ namespace ts {
|
|||
case IterationTypeKind.Next: return "nextType";
|
||||
}
|
||||
}
|
||||
|
||||
export function signatureHasRestParameter(s: Signature) {
|
||||
return !!(s.flags & SignatureFlags.HasRestParameter);
|
||||
}
|
||||
|
||||
export function signatureHasLiteralTypes(s: Signature) {
|
||||
return !!(s.flags & SignatureFlags.HasLiteralTypes);
|
||||
}
|
||||
|
||||
export function signatureIsOptionalCall(s: Signature) {
|
||||
return !!(s.flags & SignatureFlags.IsOptionalCall);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
namespace ts {
|
||||
// WARNING: The script `configureNightly.ts` uses a regexp to parse out these values.
|
||||
// If changing the text in this section, be sure to test `configureNightly` too.
|
||||
export const versionMajorMinor = "3.7";
|
||||
export const versionMajorMinor = "3.8";
|
||||
/** The version of the TypeScript compiler release */
|
||||
export const version = `${versionMajorMinor}.0-dev`;
|
||||
}
|
||||
|
|
|
@ -96,35 +96,51 @@ namespace ts {
|
|||
if (existingDirectories.has(directoryPath)) {
|
||||
return true;
|
||||
}
|
||||
if (system.directoryExists(directoryPath)) {
|
||||
if ((compilerHost.directoryExists || system.directoryExists)(directoryPath)) {
|
||||
existingDirectories.set(directoryPath, true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function ensureDirectoriesExist(directoryPath: string) {
|
||||
if (directoryPath.length > getRootLength(directoryPath) && !directoryExists(directoryPath)) {
|
||||
const parentDirectory = getDirectoryPath(directoryPath);
|
||||
ensureDirectoriesExist(parentDirectory);
|
||||
if (compilerHost.createDirectory) {
|
||||
compilerHost.createDirectory(directoryPath);
|
||||
}
|
||||
else {
|
||||
system.createDirectory(directoryPath);
|
||||
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void) {
|
||||
try {
|
||||
performance.mark("beforeIOWrite");
|
||||
|
||||
// NOTE: If patchWriteFileEnsuringDirectory has been called,
|
||||
// the system.writeFile will do its own directory creation and
|
||||
// the ensureDirectoriesExist call will always be redundant.
|
||||
writeFileEnsuringDirectories(
|
||||
fileName,
|
||||
data,
|
||||
writeByteOrderMark,
|
||||
(path, data, writeByteOrderMark) => writeFileWorker(path, data, writeByteOrderMark),
|
||||
path => (compilerHost.createDirectory || system.createDirectory)(path),
|
||||
path => directoryExists(path));
|
||||
|
||||
performance.mark("afterIOWrite");
|
||||
performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite");
|
||||
}
|
||||
catch (e) {
|
||||
if (onError) {
|
||||
onError(e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let outputFingerprints: Map<OutputFingerprint>;
|
||||
function writeFileWorker(fileName: string, data: string, writeByteOrderMark: boolean) {
|
||||
if (!isWatchSet(options) || !system.createHash || !system.getModifiedTime) {
|
||||
system.writeFile(fileName, data, writeByteOrderMark);
|
||||
return;
|
||||
}
|
||||
|
||||
function writeFileIfUpdated(fileName: string, data: string, writeByteOrderMark: boolean): void {
|
||||
if (!outputFingerprints) {
|
||||
outputFingerprints = createMap<OutputFingerprint>();
|
||||
}
|
||||
|
||||
const hash = system.createHash!(data); // TODO: GH#18217
|
||||
const mtimeBefore = system.getModifiedTime!(fileName); // TODO: GH#18217
|
||||
const hash = system.createHash(data);
|
||||
const mtimeBefore = system.getModifiedTime(fileName);
|
||||
|
||||
if (mtimeBefore) {
|
||||
const fingerprint = outputFingerprints.get(fileName);
|
||||
|
@ -139,7 +155,7 @@ namespace ts {
|
|||
|
||||
system.writeFile(fileName, data, writeByteOrderMark);
|
||||
|
||||
const mtimeAfter = system.getModifiedTime!(fileName) || missingFileModifiedTime; // TODO: GH#18217
|
||||
const mtimeAfter = system.getModifiedTime(fileName) || missingFileModifiedTime;
|
||||
|
||||
outputFingerprints.set(fileName, {
|
||||
hash,
|
||||
|
@ -148,28 +164,6 @@ namespace ts {
|
|||
});
|
||||
}
|
||||
|
||||
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void) {
|
||||
try {
|
||||
performance.mark("beforeIOWrite");
|
||||
ensureDirectoriesExist(getDirectoryPath(normalizePath(fileName)));
|
||||
|
||||
if (isWatchSet(options) && system.createHash && system.getModifiedTime) {
|
||||
writeFileIfUpdated(fileName, data, writeByteOrderMark);
|
||||
}
|
||||
else {
|
||||
system.writeFile(fileName, data, writeByteOrderMark);
|
||||
}
|
||||
|
||||
performance.mark("afterIOWrite");
|
||||
performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite");
|
||||
}
|
||||
catch (e) {
|
||||
if (onError) {
|
||||
onError(e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getDefaultLibLocation(): string {
|
||||
return getDirectoryPath(normalizePath(system.getExecutingFilePath()));
|
||||
}
|
||||
|
|
|
@ -522,17 +522,6 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function recursiveCreateDirectory(directoryPath: string, sys: System) {
|
||||
const basePath = getDirectoryPath(directoryPath);
|
||||
const shouldCreateParent = basePath !== "" && directoryPath !== basePath && !sys.directoryExists(basePath);
|
||||
if (shouldCreateParent) {
|
||||
recursiveCreateDirectory(basePath, sys);
|
||||
}
|
||||
if (shouldCreateParent || !sys.directoryExists(directoryPath)) {
|
||||
sys.createDirectory(directoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* patch writefile to create folder before writing the file
|
||||
*/
|
||||
|
@ -540,13 +529,14 @@ namespace ts {
|
|||
export function patchWriteFileEnsuringDirectory(sys: System) {
|
||||
// patch writefile to create folder before writing the file
|
||||
const originalWriteFile = sys.writeFile;
|
||||
sys.writeFile = (path, data, writeBom) => {
|
||||
const directoryPath = getDirectoryPath(normalizeSlashes(path));
|
||||
if (directoryPath && !sys.directoryExists(directoryPath)) {
|
||||
recursiveCreateDirectory(directoryPath, sys);
|
||||
}
|
||||
originalWriteFile.call(sys, path, data, writeBom);
|
||||
};
|
||||
sys.writeFile = (path, data, writeBom) =>
|
||||
writeFileEnsuringDirectories(
|
||||
path,
|
||||
data,
|
||||
!!writeBom,
|
||||
(path, data, writeByteOrderMark) => originalWriteFile.call(sys, path, data, writeByteOrderMark),
|
||||
path => sys.createDirectory(path),
|
||||
path => sys.directoryExists(path));
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
|
|
|
@ -3451,8 +3451,7 @@ namespace ts {
|
|||
resolvedReturnType: Type,
|
||||
typePredicate: TypePredicate | undefined,
|
||||
minArgumentCount: number,
|
||||
hasRestParameter: boolean,
|
||||
hasLiteralTypes: boolean,
|
||||
flags: SignatureFlags
|
||||
): Signature;
|
||||
/* @internal */ createSymbol(flags: SymbolFlags, name: __String): TransientSymbol;
|
||||
/* @internal */ createIndexInfo(type: Type, isReadonly: boolean, declaration?: SignatureDeclaration): IndexInfo;
|
||||
|
@ -4671,7 +4670,22 @@ namespace ts {
|
|||
Construct,
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export const enum SignatureFlags {
|
||||
None = 0,
|
||||
HasRestParameter = 1 << 0, // Indicates last parameter is rest parameter
|
||||
HasLiteralTypes = 1 << 1, // Indicates signature is specialized
|
||||
IsOptionalCall = 1 << 2, // Indicates signature comes from a CallChain
|
||||
|
||||
// We do not propagate `IsOptionalCall` to instantiated signatures, as that would result in us
|
||||
// attempting to add `| undefined` on each recursive call to `getReturnTypeOfSignature` when
|
||||
// instantiating the return type.
|
||||
PropagatingFlags = HasRestParameter | HasLiteralTypes,
|
||||
}
|
||||
|
||||
export interface Signature {
|
||||
/* @internal */ flags: SignatureFlags;
|
||||
/* @internal */ checker?: TypeChecker;
|
||||
declaration?: SignatureDeclaration | JSDocSignature; // Originating declaration
|
||||
typeParameters?: readonly TypeParameter[]; // Type parameters (undefined if non-generic)
|
||||
parameters: readonly Symbol[]; // Parameters
|
||||
|
@ -4688,10 +4702,6 @@ namespace ts {
|
|||
/* @internal */
|
||||
minArgumentCount: number; // Number of non-optional parameters
|
||||
/* @internal */
|
||||
hasRestParameter: boolean; // True if last parameter is rest parameter
|
||||
/* @internal */
|
||||
hasLiteralTypes: boolean; // True if specialized
|
||||
/* @internal */
|
||||
target?: Signature; // Instantiation target
|
||||
/* @internal */
|
||||
mapper?: TypeMapper; // Instantiation mapper
|
||||
|
@ -4702,11 +4712,11 @@ namespace ts {
|
|||
/* @internal */
|
||||
canonicalSignatureCache?: Signature; // Canonical version of signature (deferred)
|
||||
/* @internal */
|
||||
optionalCallSignatureCache?: Signature; // Optional chained call version of signature (deferred)
|
||||
/* @internal */
|
||||
isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison
|
||||
/* @internal */
|
||||
instantiations?: Map<Signature>; // Generic signature instantiation cache
|
||||
/* @internal */
|
||||
isOptionalCall?: boolean;
|
||||
}
|
||||
|
||||
export const enum IndexKind {
|
||||
|
@ -6442,6 +6452,7 @@ namespace ts {
|
|||
readonly disableSuggestions?: boolean;
|
||||
readonly quotePreference?: "auto" | "double" | "single";
|
||||
readonly includeCompletionsForModuleExports?: boolean;
|
||||
readonly includeAutomaticOptionalChainCompletions?: boolean;
|
||||
readonly includeCompletionsWithInsertText?: boolean;
|
||||
readonly importModuleSpecifierPreference?: "relative" | "non-relative";
|
||||
/** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */
|
||||
|
|
|
@ -2061,26 +2061,30 @@ namespace ts {
|
|||
isBindableStaticNameExpression(expr.arguments[0], /*excludeThisKeyword*/ true);
|
||||
}
|
||||
|
||||
export function isBindableStaticElementAccessExpression(node: Node, excludeThisKeyword?: boolean): node is BindableStaticElementAccessExpression {
|
||||
return isLiteralLikeElementAccess(node)
|
||||
&& ((!excludeThisKeyword && node.expression.kind === SyntaxKind.ThisKeyword) ||
|
||||
isEntityNameExpression(node.expression) ||
|
||||
isBindableStaticElementAccessExpression(node.expression, /*excludeThisKeyword*/ true));
|
||||
}
|
||||
|
||||
/** x.y OR x[0] */
|
||||
export function isLiteralLikeAccess(node: Node): node is LiteralLikeElementAccessExpression | PropertyAccessExpression {
|
||||
return isPropertyAccessExpression(node) || isLiteralLikeElementAccess(node);
|
||||
}
|
||||
|
||||
/** x[0] OR x['a'] OR x[Symbol.y] */
|
||||
export function isLiteralLikeElementAccess(node: Node): node is LiteralLikeElementAccessExpression {
|
||||
return isElementAccessExpression(node) && (
|
||||
isStringOrNumericLiteralLike(node.argumentExpression) ||
|
||||
isWellKnownSymbolSyntactically(node.argumentExpression));
|
||||
}
|
||||
|
||||
/** Any series of property and element accesses. */
|
||||
export function isBindableStaticAccessExpression(node: Node, excludeThisKeyword?: boolean): node is BindableStaticAccessExpression {
|
||||
return isPropertyAccessExpression(node) && (!excludeThisKeyword && node.expression.kind === SyntaxKind.ThisKeyword || isBindableStaticNameExpression(node.expression, /*excludeThisKeyword*/ true))
|
||||
|| isBindableStaticElementAccessExpression(node, excludeThisKeyword);
|
||||
|| isBindableStaticElementAccessExpression(node, excludeThisKeyword);
|
||||
}
|
||||
|
||||
/** Any series of property and element accesses, ending in a literal element access */
|
||||
export function isBindableStaticElementAccessExpression(node: Node, excludeThisKeyword?: boolean): node is BindableStaticElementAccessExpression {
|
||||
return isLiteralLikeElementAccess(node)
|
||||
&& ((!excludeThisKeyword && node.expression.kind === SyntaxKind.ThisKeyword) ||
|
||||
isEntityNameExpression(node.expression) ||
|
||||
isBindableStaticAccessExpression(node.expression, /*excludeThisKeyword*/ true));
|
||||
}
|
||||
|
||||
export function isBindableStaticNameExpression(node: Node, excludeThisKeyword?: boolean): node is BindableStaticNameExpression {
|
||||
|
@ -2111,7 +2115,7 @@ namespace ts {
|
|||
if (expr.operatorToken.kind !== SyntaxKind.EqualsToken || !isAccessExpression(expr.left)) {
|
||||
return AssignmentDeclarationKind.None;
|
||||
}
|
||||
if (isBindableStaticNameExpression(expr.left.expression) && getElementOrPropertyAccessName(expr.left) === "prototype" && isObjectLiteralExpression(getInitializerOfBinaryExpression(expr))) {
|
||||
if (isBindableStaticNameExpression(expr.left.expression, /*excludeThisKeyword*/ true) && getElementOrPropertyAccessName(expr.left) === "prototype" && isObjectLiteralExpression(getInitializerOfBinaryExpression(expr))) {
|
||||
// F.prototype = { ... }
|
||||
return AssignmentDeclarationKind.Prototype;
|
||||
}
|
||||
|
@ -2179,8 +2183,10 @@ namespace ts {
|
|||
// exports.name = expr OR module.exports.name = expr OR exports["name"] = expr ...
|
||||
return AssignmentDeclarationKind.ExportsProperty;
|
||||
}
|
||||
// F.G...x = expr
|
||||
return AssignmentDeclarationKind.Property;
|
||||
if (isBindableStaticNameExpression(lhs, /*excludeThisKeyword*/ true) || (isElementAccessExpression(lhs) && isDynamicName(lhs) && lhs.expression.kind !== SyntaxKind.ThisKeyword)) {
|
||||
// F.G...x = expr
|
||||
return AssignmentDeclarationKind.Property;
|
||||
}
|
||||
}
|
||||
|
||||
return AssignmentDeclarationKind.None;
|
||||
|
@ -3700,6 +3706,36 @@ namespace ts {
|
|||
}, sourceFiles);
|
||||
}
|
||||
|
||||
function ensureDirectoriesExist(
|
||||
directoryPath: string,
|
||||
createDirectory: (path: string) => void,
|
||||
directoryExists: (path: string) => boolean): void {
|
||||
if (directoryPath.length > getRootLength(directoryPath) && !directoryExists(directoryPath)) {
|
||||
const parentDirectory = getDirectoryPath(directoryPath);
|
||||
ensureDirectoriesExist(parentDirectory, createDirectory, directoryExists);
|
||||
createDirectory(directoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
export function writeFileEnsuringDirectories(
|
||||
path: string,
|
||||
data: string,
|
||||
writeByteOrderMark: boolean,
|
||||
writeFile: (path: string, data: string, writeByteOrderMark: boolean) => void,
|
||||
createDirectory: (path: string) => void,
|
||||
directoryExists: (path: string) => boolean): void {
|
||||
|
||||
// PERF: Checking for directory existence is expensive. Instead, assume the directory exists
|
||||
// and fall back to creating it if the file write fails.
|
||||
try {
|
||||
writeFile(path, data, writeByteOrderMark);
|
||||
}
|
||||
catch {
|
||||
ensureDirectoriesExist(getDirectoryPath(normalizePath(path)), createDirectory, directoryExists);
|
||||
writeFile(path, data, writeByteOrderMark);
|
||||
}
|
||||
}
|
||||
|
||||
export function getLineOfLocalPosition(currentSourceFile: SourceFile, pos: number) {
|
||||
return getLineAndCharacterOfPosition(currentSourceFile, pos).line;
|
||||
}
|
||||
|
@ -5911,6 +5947,18 @@ namespace ts {
|
|||
|| kind === SyntaxKind.CallExpression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a node is the expression preceding an optional chain (i.e. `a` in `a?.b`).
|
||||
*/
|
||||
/* @internal */
|
||||
export function isExpressionOfOptionalChainRoot(node: Node): node is Expression & { parent: OptionalChainRoot } {
|
||||
return isOptionalChainRoot(node.parent) && node.parent.expression === node;
|
||||
}
|
||||
|
||||
export function isNullishCoalesce(node: Node) {
|
||||
return node.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>node).operatorToken.kind === SyntaxKind.QuestionQuestionToken;
|
||||
}
|
||||
|
||||
export function isNewExpression(node: Node): node is NewExpression {
|
||||
return node.kind === SyntaxKind.NewExpression;
|
||||
}
|
||||
|
@ -7310,7 +7358,7 @@ namespace ts {
|
|||
getSourceFileConstructor(): new (kind: SyntaxKind.SourceFile, pos?: number, end?: number) => SourceFile;
|
||||
getSymbolConstructor(): new (flags: SymbolFlags, name: __String) => Symbol;
|
||||
getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type;
|
||||
getSignatureConstructor(): new (checker: TypeChecker) => Signature;
|
||||
getSignatureConstructor(): new (checker: TypeChecker, flags: SignatureFlags) => Signature;
|
||||
getSourceMapSourceConstructor(): new (fileName: string, text: string, skipTrivia?: (pos: number) => number) => SourceMapSource;
|
||||
}
|
||||
|
||||
|
@ -7331,7 +7379,12 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function Signature() {}
|
||||
function Signature(this: Signature, checker: TypeChecker, flags: SignatureFlags) {
|
||||
this.flags = flags;
|
||||
if (Debug.isDebugging) {
|
||||
this.checker = checker;
|
||||
}
|
||||
}
|
||||
|
||||
function Node(this: Node, kind: SyntaxKind, pos: number, end: number) {
|
||||
this.pos = pos;
|
||||
|
|
|
@ -303,20 +303,20 @@ namespace ts {
|
|||
readDirectory: maybeBind(host, host.readDirectory),
|
||||
};
|
||||
|
||||
function ensureDirectoriesExist(directoryPath: string) {
|
||||
if (directoryPath.length > getRootLength(directoryPath) && !host.directoryExists!(directoryPath)) {
|
||||
const parentDirectory = getDirectoryPath(directoryPath);
|
||||
ensureDirectoriesExist(parentDirectory);
|
||||
if (host.createDirectory) host.createDirectory(directoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
function writeFile(fileName: string, text: string, writeByteOrderMark: boolean, onError: (message: string) => void) {
|
||||
try {
|
||||
performance.mark("beforeIOWrite");
|
||||
ensureDirectoriesExist(getDirectoryPath(normalizePath(fileName)));
|
||||
|
||||
host.writeFile!(fileName, text, writeByteOrderMark);
|
||||
// NOTE: If patchWriteFileEnsuringDirectory has been called,
|
||||
// the host.writeFile will do its own directory creation and
|
||||
// the ensureDirectoriesExist call will always be redundant.
|
||||
writeFileEnsuringDirectories(
|
||||
fileName,
|
||||
text,
|
||||
writeByteOrderMark,
|
||||
(path, data, writeByteOrderMark) => host.writeFile!(path, data, writeByteOrderMark),
|
||||
path => host.createDirectory!(path),
|
||||
path => host.directoryExists!(path));
|
||||
|
||||
performance.mark("afterIOWrite");
|
||||
performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite");
|
||||
|
|
|
@ -1359,9 +1359,12 @@ namespace ts.server {
|
|||
return;
|
||||
}
|
||||
|
||||
// Search our peer node_modules, then any globally-specified probe paths
|
||||
// ../../.. to walk from X/node_modules/typescript/lib/tsserver.js to X/node_modules/
|
||||
const searchPaths = [combinePaths(this.projectService.getExecutingFilePath(), "../../.."), ...this.projectService.pluginProbeLocations];
|
||||
// Search any globally-specified probe paths, then our peer node_modules
|
||||
const searchPaths = [
|
||||
...this.projectService.pluginProbeLocations,
|
||||
// ../../.. to walk from X/node_modules/typescript/lib/tsserver.js to X/node_modules/
|
||||
combinePaths(this.projectService.getExecutingFilePath(), "../../.."),
|
||||
];
|
||||
|
||||
if (this.projectService.globalPlugins) {
|
||||
// Enable global plugins with synthetic configuration entries
|
||||
|
|
|
@ -3007,6 +3007,12 @@ namespace ts.server.protocol {
|
|||
* For those entries, The `insertText` and `replacementSpan` properties will be set to change from `.x` property access to `["x"]`.
|
||||
*/
|
||||
readonly includeCompletionsWithInsertText?: boolean;
|
||||
/**
|
||||
* Unless this option is `false`, or `includeCompletionsWithInsertText` is not enabled,
|
||||
* member completion lists triggered with `.` will include entries on potentially-null and potentially-undefined
|
||||
* values, with insertion text to replace preceding `.` tokens with `?.`.
|
||||
*/
|
||||
readonly includeAutomaticOptionalChainCompletions?: boolean;
|
||||
readonly importModuleSpecifierPreference?: "relative" | "non-relative";
|
||||
readonly allowTextChangesInNewFiles?: boolean;
|
||||
readonly lazyConfiguredProjectsFromExternalProject?: boolean;
|
||||
|
|
|
@ -233,14 +233,14 @@ namespace ts.codefix {
|
|||
let someSigHasRestParameter = false;
|
||||
for (const sig of signatures) {
|
||||
minArgumentCount = Math.min(sig.minArgumentCount, minArgumentCount);
|
||||
if (sig.hasRestParameter) {
|
||||
if (signatureHasRestParameter(sig)) {
|
||||
someSigHasRestParameter = true;
|
||||
}
|
||||
if (sig.parameters.length >= maxArgsSignature.parameters.length && (!sig.hasRestParameter || maxArgsSignature.hasRestParameter)) {
|
||||
if (sig.parameters.length >= maxArgsSignature.parameters.length && (!signatureHasRestParameter(sig) || signatureHasRestParameter(maxArgsSignature))) {
|
||||
maxArgsSignature = sig;
|
||||
}
|
||||
}
|
||||
const maxNonRestArgs = maxArgsSignature.parameters.length - (maxArgsSignature.hasRestParameter ? 1 : 0);
|
||||
const maxNonRestArgs = maxArgsSignature.parameters.length - (signatureHasRestParameter(maxArgsSignature) ? 1 : 0);
|
||||
const maxArgsParameterSymbolNames = maxArgsSignature.parameters.map(symbol => symbol.name);
|
||||
|
||||
const parameters = createDummyParameters(maxNonRestArgs, maxArgsParameterSymbolNames, /* types */ undefined, minArgumentCount, /*inJs*/ false);
|
||||
|
|
|
@ -1112,7 +1112,7 @@ namespace ts.codefix {
|
|||
}
|
||||
const returnType = combineFromUsage(combineUsages(calls.map(call => call.return_)));
|
||||
// TODO: GH#18217
|
||||
return checker.createSignature(/*declaration*/ undefined!, /*typeParameters*/ undefined, /*thisParameter*/ undefined, parameters, returnType, /*typePredicate*/ undefined, length, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
|
||||
return checker.createSignature(/*declaration*/ undefined!, /*typeParameters*/ undefined, /*thisParameter*/ undefined, parameters, returnType, /*typePredicate*/ undefined, length, SignatureFlags.None);
|
||||
}
|
||||
|
||||
function addCandidateType(usage: Usage, type: Type | undefined) {
|
||||
|
|
|
@ -338,6 +338,7 @@ namespace ts.Completions {
|
|||
): CompletionEntry | undefined {
|
||||
let insertText: string | undefined;
|
||||
let replacementSpan: TextSpan | undefined;
|
||||
|
||||
const insertQuestionDot = origin && originIsNullableMember(origin);
|
||||
const useBraces = origin && originIsSymbolMember(origin) || needsConvertPropertyAccess;
|
||||
if (origin && originIsThisType(origin)) {
|
||||
|
@ -780,7 +781,7 @@ namespace ts.Completions {
|
|||
sourceFile: SourceFile,
|
||||
isUncheckedFile: boolean,
|
||||
position: number,
|
||||
preferences: Pick<UserPreferences, "includeCompletionsForModuleExports" | "includeCompletionsWithInsertText">,
|
||||
preferences: Pick<UserPreferences, "includeCompletionsForModuleExports" | "includeCompletionsWithInsertText" | "includeAutomaticOptionalChainCompletions">,
|
||||
detailsEntryId: CompletionEntryIdentifier | undefined,
|
||||
host: LanguageServiceHost,
|
||||
): CompletionData | Request | undefined {
|
||||
|
@ -1116,8 +1117,17 @@ namespace ts.Completions {
|
|||
let type = typeChecker.getTypeOfSymbolAtLocation(symbol, node).getNonOptionalType();
|
||||
let insertQuestionDot = false;
|
||||
if (type.isNullableType()) {
|
||||
insertQuestionDot = isRightOfDot && !isRightOfQuestionDot;
|
||||
type = type.getNonNullableType();
|
||||
const canCorrectToQuestionDot =
|
||||
isRightOfDot &&
|
||||
!isRightOfQuestionDot &&
|
||||
preferences.includeAutomaticOptionalChainCompletions !== false;
|
||||
|
||||
if (canCorrectToQuestionDot || isRightOfQuestionDot) {
|
||||
type = type.getNonNullableType();
|
||||
if (canCorrectToQuestionDot) {
|
||||
insertQuestionDot = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
addTypeProperties(type, !!(node.flags & NodeFlags.AwaitContext), insertQuestionDot);
|
||||
}
|
||||
|
@ -1137,8 +1147,17 @@ namespace ts.Completions {
|
|||
let type = typeChecker.getTypeAtLocation(node).getNonOptionalType();
|
||||
let insertQuestionDot = false;
|
||||
if (type.isNullableType()) {
|
||||
insertQuestionDot = isRightOfDot && !isRightOfQuestionDot;
|
||||
type = type.getNonNullableType();
|
||||
const canCorrectToQuestionDot =
|
||||
isRightOfDot &&
|
||||
!isRightOfQuestionDot &&
|
||||
preferences.includeAutomaticOptionalChainCompletions !== false;
|
||||
|
||||
if (canCorrectToQuestionDot || isRightOfQuestionDot) {
|
||||
type = type.getNonNullableType();
|
||||
if (canCorrectToQuestionDot) {
|
||||
insertQuestionDot = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
addTypeProperties(type, !!(node.flags & NodeFlags.AwaitContext), insertQuestionDot);
|
||||
}
|
||||
|
|
|
@ -584,7 +584,7 @@ namespace ts.FindAllReferences.Core {
|
|||
}
|
||||
|
||||
function getReferencedSymbolsForModuleIfDeclaredBySourceFile(symbol: Symbol, program: Program, sourceFiles: readonly SourceFile[], cancellationToken: CancellationToken, options: Options, sourceFilesSet: ReadonlyMap<true>) {
|
||||
const moduleSourceFile = symbol.flags & SymbolFlags.Module ? find(symbol.declarations, isSourceFile) : undefined;
|
||||
const moduleSourceFile = (symbol.flags & SymbolFlags.Module) && symbol.declarations && find(symbol.declarations, isSourceFile);
|
||||
if (!moduleSourceFile) return undefined;
|
||||
const exportEquals = symbol.exports!.get(InternalSymbolName.ExportEquals);
|
||||
// If !!exportEquals, we're about to add references to `import("mod")` anyway, so don't double-count them.
|
||||
|
|
|
@ -648,7 +648,8 @@ namespace ts.NavigationBar {
|
|||
|
||||
const declName = getNameOfDeclaration(<Declaration>node);
|
||||
if (declName && isPropertyName(declName)) {
|
||||
return unescapeLeadingUnderscores(getPropertyNameForPropertyNameNode(declName)!); // TODO: GH#18217
|
||||
const propertyName = getPropertyNameForPropertyNameNode(declName);
|
||||
return propertyName && unescapeLeadingUnderscores(propertyName);
|
||||
}
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.FunctionExpression:
|
||||
|
|
|
@ -464,6 +464,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
class SignatureObject implements Signature {
|
||||
flags: SignatureFlags;
|
||||
checker: TypeChecker;
|
||||
declaration!: SignatureDeclaration;
|
||||
typeParameters?: TypeParameter[];
|
||||
|
@ -473,8 +474,6 @@ namespace ts {
|
|||
resolvedTypePredicate: TypePredicate | undefined;
|
||||
minTypeArgumentCount!: number;
|
||||
minArgumentCount!: number;
|
||||
hasRestParameter!: boolean;
|
||||
hasLiteralTypes!: boolean;
|
||||
|
||||
// Undefined is used to indicate the value has not been computed. If, after computing, the
|
||||
// symbol has no doc comment, then the empty array will be returned.
|
||||
|
@ -484,9 +483,11 @@ namespace ts {
|
|||
// symbol has no doc comment, then the empty array will be returned.
|
||||
jsDocTags?: JSDocTagInfo[];
|
||||
|
||||
constructor(checker: TypeChecker) {
|
||||
constructor(checker: TypeChecker, flags: SignatureFlags) {
|
||||
this.checker = checker;
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
getDeclaration(): SignatureDeclaration {
|
||||
return this.declaration;
|
||||
}
|
||||
|
|
|
@ -204,7 +204,7 @@ namespace ts.Completions.StringCompletions {
|
|||
const candidates: Signature[] = [];
|
||||
checker.getResolvedSignature(argumentInfo.invocation, candidates, argumentInfo.argumentCount);
|
||||
const types = flatMap(candidates, candidate => {
|
||||
if (!candidate.hasRestParameter && argumentInfo.argumentCount > candidate.parameters.length) return;
|
||||
if (!signatureHasRestParameter(candidate) && argumentInfo.argumentCount > candidate.parameters.length) return;
|
||||
const type = checker.getParameterType(candidate, argumentInfo.argumentIndex);
|
||||
isNewIdentifier = isNewIdentifier || !!(type.flags & TypeFlags.String);
|
||||
return getStringLiteralTypes(type, uniques);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../tsconfig-base",
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outFile": "../../built/local/tsc.release.js",
|
||||
"stripInternal": true,
|
||||
|
@ -8,11 +8,8 @@
|
|||
"declarationMap": false,
|
||||
"sourceMap": false,
|
||||
"composite": false,
|
||||
"incremental": true
|
||||
"incremental": true
|
||||
},
|
||||
"files": [
|
||||
"tsc.ts"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../compiler/tsconfig.release.json", "prepend": true }
|
||||
]
|
||||
|
|
142
tests/baselines/reference/anonClassDeclarationEmitIsAnon.js
Normal file
142
tests/baselines/reference/anonClassDeclarationEmitIsAnon.js
Normal file
|
@ -0,0 +1,142 @@
|
|||
//// [tests/cases/compiler/anonClassDeclarationEmitIsAnon.ts] ////
|
||||
|
||||
//// [wrapClass.ts]
|
||||
export function wrapClass(param: any) {
|
||||
return class Wrapped {
|
||||
foo() {
|
||||
return param;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type Constructor<T = {}> = new (...args: any[]) => T;
|
||||
|
||||
export function Timestamped<TBase extends Constructor>(Base: TBase) {
|
||||
return class extends Base {
|
||||
timestamp = Date.now();
|
||||
};
|
||||
}
|
||||
|
||||
//// [index.ts]
|
||||
import { wrapClass, Timestamped } from "./wrapClass";
|
||||
|
||||
export default wrapClass(0);
|
||||
|
||||
// Simple class
|
||||
export class User {
|
||||
name = '';
|
||||
}
|
||||
|
||||
// User that is Timestamped
|
||||
export class TimestampedUser extends Timestamped(User) {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
//// [wrapClass.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
function wrapClass(param) {
|
||||
return /** @class */ (function () {
|
||||
function Wrapped() {
|
||||
}
|
||||
Wrapped.prototype.foo = function () {
|
||||
return param;
|
||||
};
|
||||
return Wrapped;
|
||||
}());
|
||||
}
|
||||
exports.wrapClass = wrapClass;
|
||||
function Timestamped(Base) {
|
||||
return /** @class */ (function (_super) {
|
||||
__extends(class_1, _super);
|
||||
function class_1() {
|
||||
var _this = _super !== null && _super.apply(this, arguments) || this;
|
||||
_this.timestamp = Date.now();
|
||||
return _this;
|
||||
}
|
||||
return class_1;
|
||||
}(Base));
|
||||
}
|
||||
exports.Timestamped = Timestamped;
|
||||
//// [index.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
exports.__esModule = true;
|
||||
var wrapClass_1 = require("./wrapClass");
|
||||
exports["default"] = wrapClass_1.wrapClass(0);
|
||||
// Simple class
|
||||
var User = /** @class */ (function () {
|
||||
function User() {
|
||||
this.name = '';
|
||||
}
|
||||
return User;
|
||||
}());
|
||||
exports.User = User;
|
||||
// User that is Timestamped
|
||||
var TimestampedUser = /** @class */ (function (_super) {
|
||||
__extends(TimestampedUser, _super);
|
||||
function TimestampedUser() {
|
||||
return _super.call(this) || this;
|
||||
}
|
||||
return TimestampedUser;
|
||||
}(wrapClass_1.Timestamped(User)));
|
||||
exports.TimestampedUser = TimestampedUser;
|
||||
|
||||
|
||||
//// [wrapClass.d.ts]
|
||||
export declare function wrapClass(param: any): {
|
||||
new (): {
|
||||
foo(): any;
|
||||
};
|
||||
};
|
||||
export declare type Constructor<T = {}> = new (...args: any[]) => T;
|
||||
export declare function Timestamped<TBase extends Constructor>(Base: TBase): {
|
||||
new (...args: any[]): {
|
||||
timestamp: number;
|
||||
};
|
||||
} & TBase;
|
||||
//// [index.d.ts]
|
||||
declare const _default: {
|
||||
new (): {
|
||||
foo(): any;
|
||||
};
|
||||
};
|
||||
export default _default;
|
||||
export declare class User {
|
||||
name: string;
|
||||
}
|
||||
declare const TimestampedUser_base: {
|
||||
new (...args: any[]): {
|
||||
timestamp: number;
|
||||
};
|
||||
} & typeof User;
|
||||
export declare class TimestampedUser extends TimestampedUser_base {
|
||||
constructor();
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
=== tests/cases/compiler/wrapClass.ts ===
|
||||
export function wrapClass(param: any) {
|
||||
>wrapClass : Symbol(wrapClass, Decl(wrapClass.ts, 0, 0))
|
||||
>param : Symbol(param, Decl(wrapClass.ts, 0, 26))
|
||||
|
||||
return class Wrapped {
|
||||
>Wrapped : Symbol(Wrapped, Decl(wrapClass.ts, 1, 10))
|
||||
|
||||
foo() {
|
||||
>foo : Symbol(Wrapped.foo, Decl(wrapClass.ts, 1, 26))
|
||||
|
||||
return param;
|
||||
>param : Symbol(param, Decl(wrapClass.ts, 0, 26))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type Constructor<T = {}> = new (...args: any[]) => T;
|
||||
>Constructor : Symbol(Constructor, Decl(wrapClass.ts, 6, 1))
|
||||
>T : Symbol(T, Decl(wrapClass.ts, 8, 24))
|
||||
>args : Symbol(args, Decl(wrapClass.ts, 8, 39))
|
||||
>T : Symbol(T, Decl(wrapClass.ts, 8, 24))
|
||||
|
||||
export function Timestamped<TBase extends Constructor>(Base: TBase) {
|
||||
>Timestamped : Symbol(Timestamped, Decl(wrapClass.ts, 8, 60))
|
||||
>TBase : Symbol(TBase, Decl(wrapClass.ts, 10, 28))
|
||||
>Constructor : Symbol(Constructor, Decl(wrapClass.ts, 6, 1))
|
||||
>Base : Symbol(Base, Decl(wrapClass.ts, 10, 55))
|
||||
>TBase : Symbol(TBase, Decl(wrapClass.ts, 10, 28))
|
||||
|
||||
return class extends Base {
|
||||
>Base : Symbol(Base, Decl(wrapClass.ts, 10, 55))
|
||||
|
||||
timestamp = Date.now();
|
||||
>timestamp : Symbol((Anonymous class).timestamp, Decl(wrapClass.ts, 11, 31))
|
||||
>Date.now : Symbol(DateConstructor.now, Decl(lib.es5.d.ts, --, --))
|
||||
>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --))
|
||||
>now : Symbol(DateConstructor.now, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/index.ts ===
|
||||
import { wrapClass, Timestamped } from "./wrapClass";
|
||||
>wrapClass : Symbol(wrapClass, Decl(index.ts, 0, 8))
|
||||
>Timestamped : Symbol(Timestamped, Decl(index.ts, 0, 19))
|
||||
|
||||
export default wrapClass(0);
|
||||
>wrapClass : Symbol(wrapClass, Decl(index.ts, 0, 8))
|
||||
|
||||
// Simple class
|
||||
export class User {
|
||||
>User : Symbol(User, Decl(index.ts, 2, 28))
|
||||
|
||||
name = '';
|
||||
>name : Symbol(User.name, Decl(index.ts, 5, 19))
|
||||
}
|
||||
|
||||
// User that is Timestamped
|
||||
export class TimestampedUser extends Timestamped(User) {
|
||||
>TimestampedUser : Symbol(TimestampedUser, Decl(index.ts, 7, 1))
|
||||
>Timestamped : Symbol(Timestamped, Decl(index.ts, 0, 19))
|
||||
>User : Symbol(User, Decl(index.ts, 2, 28))
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
=== tests/cases/compiler/wrapClass.ts ===
|
||||
export function wrapClass(param: any) {
|
||||
>wrapClass : (param: any) => typeof Wrapped
|
||||
>param : any
|
||||
|
||||
return class Wrapped {
|
||||
>class Wrapped { foo() { return param; } } : typeof Wrapped
|
||||
>Wrapped : typeof Wrapped
|
||||
|
||||
foo() {
|
||||
>foo : () => any
|
||||
|
||||
return param;
|
||||
>param : any
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type Constructor<T = {}> = new (...args: any[]) => T;
|
||||
>Constructor : Constructor<T>
|
||||
>args : any[]
|
||||
|
||||
export function Timestamped<TBase extends Constructor>(Base: TBase) {
|
||||
>Timestamped : <TBase extends Constructor<{}>>(Base: TBase) => { new (...args: any[]): (Anonymous class); prototype: Timestamped<any>.(Anonymous class); } & TBase
|
||||
>Base : TBase
|
||||
|
||||
return class extends Base {
|
||||
>class extends Base { timestamp = Date.now(); } : { new (...args: any[]): (Anonymous class); prototype: Timestamped<any>.(Anonymous class); } & TBase
|
||||
>Base : {}
|
||||
|
||||
timestamp = Date.now();
|
||||
>timestamp : number
|
||||
>Date.now() : number
|
||||
>Date.now : () => number
|
||||
>Date : DateConstructor
|
||||
>now : () => number
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/index.ts ===
|
||||
import { wrapClass, Timestamped } from "./wrapClass";
|
||||
>wrapClass : (param: any) => typeof Wrapped
|
||||
>Timestamped : <TBase extends import("tests/cases/compiler/wrapClass").Constructor<{}>>(Base: TBase) => { new (...args: any[]): (Anonymous class); prototype: Timestamped<any>.(Anonymous class); } & TBase
|
||||
|
||||
export default wrapClass(0);
|
||||
>wrapClass(0) : typeof Wrapped
|
||||
>wrapClass : (param: any) => typeof Wrapped
|
||||
>0 : 0
|
||||
|
||||
// Simple class
|
||||
export class User {
|
||||
>User : User
|
||||
|
||||
name = '';
|
||||
>name : string
|
||||
>'' : ""
|
||||
}
|
||||
|
||||
// User that is Timestamped
|
||||
export class TimestampedUser extends Timestamped(User) {
|
||||
>TimestampedUser : TimestampedUser
|
||||
>Timestamped(User) : Timestamped<typeof User>.(Anonymous class) & User
|
||||
>Timestamped : <TBase extends import("tests/cases/compiler/wrapClass").Constructor<{}>>(Base: TBase) => { new (...args: any[]): (Anonymous class); prototype: Timestamped<any>.(Anonymous class); } & TBase
|
||||
>User : typeof User
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
>super() : void
|
||||
>super : { new (...args: any[]): Timestamped<typeof User>.(Anonymous class); prototype: Timestamped<any>.(Anonymous class); } & typeof User
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ and limitations under the License.
|
|||
***************************************************************************** */
|
||||
|
||||
declare namespace ts {
|
||||
const versionMajorMinor = "3.7";
|
||||
const versionMajorMinor = "3.8";
|
||||
/** The version of the TypeScript compiler release */
|
||||
const version: string;
|
||||
}
|
||||
|
@ -3171,6 +3171,7 @@ declare namespace ts {
|
|||
readonly disableSuggestions?: boolean;
|
||||
readonly quotePreference?: "auto" | "double" | "single";
|
||||
readonly includeCompletionsForModuleExports?: boolean;
|
||||
readonly includeAutomaticOptionalChainCompletions?: boolean;
|
||||
readonly includeCompletionsWithInsertText?: boolean;
|
||||
readonly importModuleSpecifierPreference?: "relative" | "non-relative";
|
||||
/** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */
|
||||
|
@ -3524,6 +3525,7 @@ declare namespace ts {
|
|||
function isCallExpression(node: Node): node is CallExpression;
|
||||
function isCallChain(node: Node): node is CallChain;
|
||||
function isOptionalChain(node: Node): node is PropertyAccessChain | ElementAccessChain | CallChain;
|
||||
function isNullishCoalesce(node: Node): boolean;
|
||||
function isNewExpression(node: Node): node is NewExpression;
|
||||
function isTaggedTemplateExpression(node: Node): node is TaggedTemplateExpression;
|
||||
function isTypeAssertion(node: Node): node is TypeAssertion;
|
||||
|
@ -8295,6 +8297,12 @@ declare namespace ts.server.protocol {
|
|||
* For those entries, The `insertText` and `replacementSpan` properties will be set to change from `.x` property access to `["x"]`.
|
||||
*/
|
||||
readonly includeCompletionsWithInsertText?: boolean;
|
||||
/**
|
||||
* Unless this option is `false`, or `includeCompletionsWithInsertText` is not enabled,
|
||||
* member completion lists triggered with `.` will include entries on potentially-null and potentially-undefined
|
||||
* values, with insertion text to replace preceding `.` tokens with `?.`.
|
||||
*/
|
||||
readonly includeAutomaticOptionalChainCompletions?: boolean;
|
||||
readonly importModuleSpecifierPreference?: "relative" | "non-relative";
|
||||
readonly allowTextChangesInNewFiles?: boolean;
|
||||
readonly lazyConfiguredProjectsFromExternalProject?: boolean;
|
||||
|
|
|
@ -14,7 +14,7 @@ and limitations under the License.
|
|||
***************************************************************************** */
|
||||
|
||||
declare namespace ts {
|
||||
const versionMajorMinor = "3.7";
|
||||
const versionMajorMinor = "3.8";
|
||||
/** The version of the TypeScript compiler release */
|
||||
const version: string;
|
||||
}
|
||||
|
@ -3171,6 +3171,7 @@ declare namespace ts {
|
|||
readonly disableSuggestions?: boolean;
|
||||
readonly quotePreference?: "auto" | "double" | "single";
|
||||
readonly includeCompletionsForModuleExports?: boolean;
|
||||
readonly includeAutomaticOptionalChainCompletions?: boolean;
|
||||
readonly includeCompletionsWithInsertText?: boolean;
|
||||
readonly importModuleSpecifierPreference?: "relative" | "non-relative";
|
||||
/** Determines whether we import `foo/index.ts` as "foo", "foo/index", or "foo/index.js" */
|
||||
|
@ -3524,6 +3525,7 @@ declare namespace ts {
|
|||
function isCallExpression(node: Node): node is CallExpression;
|
||||
function isCallChain(node: Node): node is CallChain;
|
||||
function isOptionalChain(node: Node): node is PropertyAccessChain | ElementAccessChain | CallChain;
|
||||
function isNullishCoalesce(node: Node): boolean;
|
||||
function isNewExpression(node: Node): node is NewExpression;
|
||||
function isTaggedTemplateExpression(node: Node): node is TaggedTemplateExpression;
|
||||
function isTypeAssertion(node: Node): node is TypeAssertion;
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
tests/cases/conformance/jsdoc/callOfPropertylessConstructorFunction.js(7,1): error TS2348: Value of type 'typeof Dependency' is not callable. Did you mean to include 'new'?
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsdoc/callOfPropertylessConstructorFunction.js (1 errors) ====
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
function Dependency(j) {
|
||||
return j
|
||||
}
|
||||
Dependency({})
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS2348: Value of type 'typeof Dependency' is not callable. Did you mean to include 'new'?
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
=== tests/cases/conformance/jsdoc/callOfPropertylessConstructorFunction.js ===
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
function Dependency(j) {
|
||||
>Dependency : Symbol(Dependency, Decl(callOfPropertylessConstructorFunction.js, 0, 0))
|
||||
>j : Symbol(j, Decl(callOfPropertylessConstructorFunction.js, 3, 20))
|
||||
|
||||
return j
|
||||
>j : Symbol(j, Decl(callOfPropertylessConstructorFunction.js, 3, 20))
|
||||
}
|
||||
Dependency({})
|
||||
>Dependency : Symbol(Dependency, Decl(callOfPropertylessConstructorFunction.js, 0, 0))
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
=== tests/cases/conformance/jsdoc/callOfPropertylessConstructorFunction.js ===
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
function Dependency(j) {
|
||||
>Dependency : typeof Dependency
|
||||
>j : any
|
||||
|
||||
return j
|
||||
>j : any
|
||||
}
|
||||
Dependency({})
|
||||
>Dependency({}) : any
|
||||
>Dependency : typeof Dependency
|
||||
>{} : {}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
tests/cases/conformance/jsdoc/0.js(10,20): error TS2694: Namespace 'exports' has no exported member 'SomeName'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsdoc/0.js (1 errors) ====
|
||||
// @ts-check
|
||||
|
||||
var exports = {};
|
||||
|
||||
/**
|
||||
* @typedef {string}
|
||||
*/
|
||||
exports.SomeName;
|
||||
|
||||
/** @type {exports.SomeName} */
|
||||
~~~~~~~~
|
||||
!!! error TS2694: Namespace 'exports' has no exported member 'SomeName'.
|
||||
const myString = 'str';
|
||||
|
23
tests/baselines/reference/checkJsdocTypedefOnlySourceFile.js
Normal file
23
tests/baselines/reference/checkJsdocTypedefOnlySourceFile.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
//// [0.js]
|
||||
// @ts-check
|
||||
|
||||
var exports = {};
|
||||
|
||||
/**
|
||||
* @typedef {string}
|
||||
*/
|
||||
exports.SomeName;
|
||||
|
||||
/** @type {exports.SomeName} */
|
||||
const myString = 'str';
|
||||
|
||||
|
||||
//// [0.js]
|
||||
// @ts-check
|
||||
var exports = {};
|
||||
/**
|
||||
* @typedef {string}
|
||||
*/
|
||||
exports.SomeName;
|
||||
/** @type {exports.SomeName} */
|
||||
var myString = 'str';
|
|
@ -0,0 +1,16 @@
|
|||
=== tests/cases/conformance/jsdoc/0.js ===
|
||||
// @ts-check
|
||||
|
||||
var exports = {};
|
||||
>exports : Symbol(exports, Decl(0.js, 2, 3))
|
||||
|
||||
/**
|
||||
* @typedef {string}
|
||||
*/
|
||||
exports.SomeName;
|
||||
>exports : Symbol(exports, Decl(0.js, 2, 3))
|
||||
|
||||
/** @type {exports.SomeName} */
|
||||
const myString = 'str';
|
||||
>myString : Symbol(myString, Decl(0.js, 10, 5))
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
=== tests/cases/conformance/jsdoc/0.js ===
|
||||
// @ts-check
|
||||
|
||||
var exports = {};
|
||||
>exports : {}
|
||||
>{} : {}
|
||||
|
||||
/**
|
||||
* @typedef {string}
|
||||
*/
|
||||
exports.SomeName;
|
||||
>exports.SomeName : any
|
||||
>exports : {}
|
||||
>SomeName : any
|
||||
|
||||
/** @type {exports.SomeName} */
|
||||
const myString = 'str';
|
||||
>myString : any
|
||||
>'str' : "str"
|
||||
|
|
@ -31,9 +31,29 @@ tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(244,9): error TS
|
|||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(271,9): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(274,9): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(277,9): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(307,9): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(310,9): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(319,9): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(322,9): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(331,9): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(340,9): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(343,9): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(352,9): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(391,9): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(394,9): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(403,9): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(406,9): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(415,9): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(424,9): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(427,9): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(436,9): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(471,13): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(474,13): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(488,13): error TS2532: Object is possibly 'undefined'.
|
||||
tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(491,13): error TS2532: Object is possibly 'undefined'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts (33 errors) ====
|
||||
==== tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts (53 errors) ====
|
||||
// assignments in shortcutting chain
|
||||
declare const o: undefined | {
|
||||
[key: string]: any;
|
||||
|
@ -401,6 +421,76 @@ tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(277,9): error TS
|
|||
}
|
||||
}
|
||||
|
||||
function f15(o: Thing | undefined, value: number) {
|
||||
if (o?.foo === value) {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
if (o?.foo !== value) {
|
||||
o.foo; // Error
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (o?.foo == value) {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
if (o?.foo != value) {
|
||||
o.foo; // Error
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
}
|
||||
|
||||
function f16(o: Thing | undefined) {
|
||||
if (o?.foo === undefined) {
|
||||
o.foo; // Error
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (o?.foo !== undefined) {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
if (o?.foo == undefined) {
|
||||
o.foo; // Error
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (o?.foo != undefined) {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
}
|
||||
|
||||
function f20(o: Thing | undefined) {
|
||||
if (typeof o?.foo === "number") {
|
||||
o.foo;
|
||||
|
@ -430,4 +520,171 @@ tests/cases/conformance/controlFlow/controlFlowOptionalChain.ts(277,9): error TS
|
|||
o.baz;
|
||||
}
|
||||
}
|
||||
|
||||
function f22(o: Thing | undefined) {
|
||||
if (typeof o?.foo === "number") {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
if (typeof o?.foo !== "number") {
|
||||
o.foo; // Error
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (typeof o?.foo == "number") {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
if (typeof o?.foo != "number") {
|
||||
o.foo; // Error
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
}
|
||||
|
||||
function f23(o: Thing | undefined) {
|
||||
if (typeof o?.foo === "undefined") {
|
||||
o.foo; // Error
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (typeof o?.foo !== "undefined") {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
if (typeof o?.foo == "undefined") {
|
||||
o.foo; // Error
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (typeof o?.foo != "undefined") {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
}
|
||||
}
|
||||
|
||||
declare function assert(x: unknown): asserts x;
|
||||
declare function assertNonNull<T>(x: T): asserts x is NonNullable<T>;
|
||||
|
||||
function f30(o: Thing | undefined) {
|
||||
if (!!true) {
|
||||
assert(o?.foo);
|
||||
o.foo;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(o?.foo === 42);
|
||||
o.foo;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(typeof o?.foo === "number");
|
||||
o.foo;
|
||||
}
|
||||
if (!!true) {
|
||||
assertNonNull(o?.foo);
|
||||
o.foo;
|
||||
}
|
||||
}
|
||||
|
||||
function f40(o: Thing | undefined) {
|
||||
switch (o?.foo) {
|
||||
case "abc":
|
||||
o.foo;
|
||||
break;
|
||||
case 42:
|
||||
o.foo;
|
||||
break;
|
||||
case undefined:
|
||||
o.foo; // Error
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
break;
|
||||
default:
|
||||
o.foo; // Error
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function f41(o: Thing | undefined) {
|
||||
switch (typeof o?.foo) {
|
||||
case "string":
|
||||
o.foo;
|
||||
break;
|
||||
case "number":
|
||||
o.foo;
|
||||
break;
|
||||
case "undefined":
|
||||
o.foo; // Error
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
break;
|
||||
default:
|
||||
o.foo; // Error
|
||||
~
|
||||
!!! error TS2532: Object is possibly 'undefined'.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Repros from #34570
|
||||
|
||||
type Shape =
|
||||
| { type: 'rectangle', width: number, height: number }
|
||||
| { type: 'circle', radius: number }
|
||||
|
||||
function getArea(shape?: Shape) {
|
||||
switch (shape?.type) {
|
||||
case 'circle':
|
||||
return Math.PI * shape.radius ** 2
|
||||
case 'rectangle':
|
||||
return shape.width * shape.height
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
type Feature = {
|
||||
id: string;
|
||||
geometry?: {
|
||||
type: string;
|
||||
coordinates: number[];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
function extractCoordinates(f: Feature): number[] {
|
||||
if (f.geometry?.type !== 'test') {
|
||||
return [];
|
||||
}
|
||||
return f.geometry.coordinates;
|
||||
}
|
||||
|
|
@ -300,6 +300,60 @@ function f14(o: Thing | null) {
|
|||
}
|
||||
}
|
||||
|
||||
function f15(o: Thing | undefined, value: number) {
|
||||
if (o?.foo === value) {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
if (o?.foo !== value) {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (o?.foo == value) {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
if (o?.foo != value) {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
}
|
||||
|
||||
function f16(o: Thing | undefined) {
|
||||
if (o?.foo === undefined) {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (o?.foo !== undefined) {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
if (o?.foo == undefined) {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (o?.foo != undefined) {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
}
|
||||
|
||||
function f20(o: Thing | undefined) {
|
||||
if (typeof o?.foo === "number") {
|
||||
o.foo;
|
||||
|
@ -329,6 +383,149 @@ function f21(o: Thing | null) {
|
|||
o.baz;
|
||||
}
|
||||
}
|
||||
|
||||
function f22(o: Thing | undefined) {
|
||||
if (typeof o?.foo === "number") {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
if (typeof o?.foo !== "number") {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (typeof o?.foo == "number") {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
if (typeof o?.foo != "number") {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
}
|
||||
|
||||
function f23(o: Thing | undefined) {
|
||||
if (typeof o?.foo === "undefined") {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (typeof o?.foo !== "undefined") {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
if (typeof o?.foo == "undefined") {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (typeof o?.foo != "undefined") {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
}
|
||||
|
||||
declare function assert(x: unknown): asserts x;
|
||||
declare function assertNonNull<T>(x: T): asserts x is NonNullable<T>;
|
||||
|
||||
function f30(o: Thing | undefined) {
|
||||
if (!!true) {
|
||||
assert(o?.foo);
|
||||
o.foo;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(o?.foo === 42);
|
||||
o.foo;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(typeof o?.foo === "number");
|
||||
o.foo;
|
||||
}
|
||||
if (!!true) {
|
||||
assertNonNull(o?.foo);
|
||||
o.foo;
|
||||
}
|
||||
}
|
||||
|
||||
function f40(o: Thing | undefined) {
|
||||
switch (o?.foo) {
|
||||
case "abc":
|
||||
o.foo;
|
||||
break;
|
||||
case 42:
|
||||
o.foo;
|
||||
break;
|
||||
case undefined:
|
||||
o.foo; // Error
|
||||
break;
|
||||
default:
|
||||
o.foo; // Error
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function f41(o: Thing | undefined) {
|
||||
switch (typeof o?.foo) {
|
||||
case "string":
|
||||
o.foo;
|
||||
break;
|
||||
case "number":
|
||||
o.foo;
|
||||
break;
|
||||
case "undefined":
|
||||
o.foo; // Error
|
||||
break;
|
||||
default:
|
||||
o.foo; // Error
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Repros from #34570
|
||||
|
||||
type Shape =
|
||||
| { type: 'rectangle', width: number, height: number }
|
||||
| { type: 'circle', radius: number }
|
||||
|
||||
function getArea(shape?: Shape) {
|
||||
switch (shape?.type) {
|
||||
case 'circle':
|
||||
return Math.PI * shape.radius ** 2
|
||||
case 'rectangle':
|
||||
return shape.width * shape.height
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
type Feature = {
|
||||
id: string;
|
||||
geometry?: {
|
||||
type: string;
|
||||
coordinates: number[];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
function extractCoordinates(f: Feature): number[] {
|
||||
if (f.geometry?.type !== 'test') {
|
||||
return [];
|
||||
}
|
||||
return f.geometry.coordinates;
|
||||
}
|
||||
|
||||
|
||||
//// [controlFlowOptionalChain.js]
|
||||
|
@ -594,6 +791,60 @@ function f14(o) {
|
|||
o.bar;
|
||||
}
|
||||
}
|
||||
function f15(o, value) {
|
||||
var _a, _b, _c, _d;
|
||||
if (((_a = o) === null || _a === void 0 ? void 0 : _a.foo) === value) {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
if (((_b = o) === null || _b === void 0 ? void 0 : _b.foo) !== value) {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (((_c = o) === null || _c === void 0 ? void 0 : _c.foo) == value) {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
if (((_d = o) === null || _d === void 0 ? void 0 : _d.foo) != value) {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
}
|
||||
function f16(o) {
|
||||
var _a, _b, _c, _d;
|
||||
if (((_a = o) === null || _a === void 0 ? void 0 : _a.foo) === undefined) {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (((_b = o) === null || _b === void 0 ? void 0 : _b.foo) !== undefined) {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
if (((_c = o) === null || _c === void 0 ? void 0 : _c.foo) == undefined) {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (((_d = o) === null || _d === void 0 ? void 0 : _d.foo) != undefined) {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
}
|
||||
function f20(o) {
|
||||
var _a, _b, _c, _d;
|
||||
if (typeof ((_a = o) === null || _a === void 0 ? void 0 : _a.foo) === "number") {
|
||||
|
@ -624,3 +875,128 @@ function f21(o) {
|
|||
o.baz;
|
||||
}
|
||||
}
|
||||
function f22(o) {
|
||||
var _a, _b, _c, _d;
|
||||
if (typeof ((_a = o) === null || _a === void 0 ? void 0 : _a.foo) === "number") {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
if (typeof ((_b = o) === null || _b === void 0 ? void 0 : _b.foo) !== "number") {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (typeof ((_c = o) === null || _c === void 0 ? void 0 : _c.foo) == "number") {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
if (typeof ((_d = o) === null || _d === void 0 ? void 0 : _d.foo) != "number") {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
}
|
||||
function f23(o) {
|
||||
var _a, _b, _c, _d;
|
||||
if (typeof ((_a = o) === null || _a === void 0 ? void 0 : _a.foo) === "undefined") {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (typeof ((_b = o) === null || _b === void 0 ? void 0 : _b.foo) !== "undefined") {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
if (typeof ((_c = o) === null || _c === void 0 ? void 0 : _c.foo) == "undefined") {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (typeof ((_d = o) === null || _d === void 0 ? void 0 : _d.foo) != "undefined") {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
}
|
||||
function f30(o) {
|
||||
var _a, _b, _c, _d;
|
||||
if (!!true) {
|
||||
assert((_a = o) === null || _a === void 0 ? void 0 : _a.foo);
|
||||
o.foo;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(((_b = o) === null || _b === void 0 ? void 0 : _b.foo) === 42);
|
||||
o.foo;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(typeof ((_c = o) === null || _c === void 0 ? void 0 : _c.foo) === "number");
|
||||
o.foo;
|
||||
}
|
||||
if (!!true) {
|
||||
assertNonNull((_d = o) === null || _d === void 0 ? void 0 : _d.foo);
|
||||
o.foo;
|
||||
}
|
||||
}
|
||||
function f40(o) {
|
||||
var _a;
|
||||
switch ((_a = o) === null || _a === void 0 ? void 0 : _a.foo) {
|
||||
case "abc":
|
||||
o.foo;
|
||||
break;
|
||||
case 42:
|
||||
o.foo;
|
||||
break;
|
||||
case undefined:
|
||||
o.foo; // Error
|
||||
break;
|
||||
default:
|
||||
o.foo; // Error
|
||||
break;
|
||||
}
|
||||
}
|
||||
function f41(o) {
|
||||
var _a;
|
||||
switch (typeof ((_a = o) === null || _a === void 0 ? void 0 : _a.foo)) {
|
||||
case "string":
|
||||
o.foo;
|
||||
break;
|
||||
case "number":
|
||||
o.foo;
|
||||
break;
|
||||
case "undefined":
|
||||
o.foo; // Error
|
||||
break;
|
||||
default:
|
||||
o.foo; // Error
|
||||
break;
|
||||
}
|
||||
}
|
||||
function getArea(shape) {
|
||||
var _a;
|
||||
switch ((_a = shape) === null || _a === void 0 ? void 0 : _a.type) {
|
||||
case 'circle':
|
||||
return Math.PI * Math.pow(shape.radius, 2);
|
||||
case 'rectangle':
|
||||
return shape.width * shape.height;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
function extractCoordinates(f) {
|
||||
var _a;
|
||||
if (((_a = f.geometry) === null || _a === void 0 ? void 0 : _a.type) !== 'test') {
|
||||
return [];
|
||||
}
|
||||
return f.geometry.coordinates;
|
||||
}
|
||||
|
|
|
@ -1039,93 +1039,627 @@ function f14(o: Thing | null) {
|
|||
}
|
||||
}
|
||||
|
||||
function f20(o: Thing | undefined) {
|
||||
>f20 : Symbol(f20, Decl(controlFlowOptionalChain.ts, 299, 1))
|
||||
function f15(o: Thing | undefined, value: number) {
|
||||
>f15 : Symbol(f15, Decl(controlFlowOptionalChain.ts, 299, 1))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13))
|
||||
>Thing : Symbol(Thing, Decl(controlFlowOptionalChain.ts, 159, 1))
|
||||
>value : Symbol(value, Decl(controlFlowOptionalChain.ts, 301, 34))
|
||||
|
||||
if (typeof o?.foo === "number") {
|
||||
if (o?.foo === value) {
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>value : Symbol(value, Decl(controlFlowOptionalChain.ts, 301, 34))
|
||||
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
if (typeof o?.["foo"] === "number") {
|
||||
else {
|
||||
o.foo; // Error
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
if (o?.foo !== value) {
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>value : Symbol(value, Decl(controlFlowOptionalChain.ts, 301, 34))
|
||||
|
||||
o.foo; // Error
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
if (o?.foo == value) {
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>value : Symbol(value, Decl(controlFlowOptionalChain.ts, 301, 34))
|
||||
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
if (o?.foo != value) {
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>value : Symbol(value, Decl(controlFlowOptionalChain.ts, 301, 34))
|
||||
|
||||
o.foo; // Error
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
}
|
||||
|
||||
function f16(o: Thing | undefined) {
|
||||
>f16 : Symbol(f16, Decl(controlFlowOptionalChain.ts, 326, 1))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13))
|
||||
>Thing : Symbol(Thing, Decl(controlFlowOptionalChain.ts, 159, 1))
|
||||
|
||||
if (o?.foo === undefined) {
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
o.foo; // Error
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
if (o?.foo !== undefined) {
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
if (o?.foo == undefined) {
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
o.foo; // Error
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
if (o?.foo != undefined) {
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 328, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
}
|
||||
|
||||
function f20(o: Thing | undefined) {
|
||||
>f20 : Symbol(f20, Decl(controlFlowOptionalChain.ts, 353, 1))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 355, 13))
|
||||
>Thing : Symbol(Thing, Decl(controlFlowOptionalChain.ts, 159, 1))
|
||||
|
||||
if (typeof o?.foo === "number") {
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 355, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 355, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
if (typeof o?.["foo"] === "number") {
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 355, 13))
|
||||
|
||||
o["foo"];
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 355, 13))
|
||||
>"foo" : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
if (typeof o?.bar() === "number") {
|
||||
>o?.bar : Symbol(bar, Decl(controlFlowOptionalChain.ts, 161, 36))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 355, 13))
|
||||
>bar : Symbol(bar, Decl(controlFlowOptionalChain.ts, 161, 36))
|
||||
|
||||
o.bar;
|
||||
>o.bar : Symbol(bar, Decl(controlFlowOptionalChain.ts, 161, 36))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 355, 13))
|
||||
>bar : Symbol(bar, Decl(controlFlowOptionalChain.ts, 161, 36))
|
||||
}
|
||||
if (o?.baz instanceof Error) {
|
||||
>o?.baz : Symbol(baz, Decl(controlFlowOptionalChain.ts, 161, 51))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 355, 13))
|
||||
>baz : Symbol(baz, Decl(controlFlowOptionalChain.ts, 161, 51))
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
o.baz;
|
||||
>o.baz : Symbol(baz, Decl(controlFlowOptionalChain.ts, 161, 51))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 301, 13))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 355, 13))
|
||||
>baz : Symbol(baz, Decl(controlFlowOptionalChain.ts, 161, 51))
|
||||
}
|
||||
}
|
||||
|
||||
function f21(o: Thing | null) {
|
||||
>f21 : Symbol(f21, Decl(controlFlowOptionalChain.ts, 314, 1))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 316, 13))
|
||||
>f21 : Symbol(f21, Decl(controlFlowOptionalChain.ts, 368, 1))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 370, 13))
|
||||
>Thing : Symbol(Thing, Decl(controlFlowOptionalChain.ts, 159, 1))
|
||||
|
||||
if (typeof o?.foo === "number") {
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 316, 13))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 370, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 316, 13))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 370, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
if (typeof o?.["foo"] === "number") {
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 316, 13))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 370, 13))
|
||||
|
||||
o["foo"];
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 316, 13))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 370, 13))
|
||||
>"foo" : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
if (typeof o?.bar() === "number") {
|
||||
>o?.bar : Symbol(bar, Decl(controlFlowOptionalChain.ts, 161, 36))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 316, 13))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 370, 13))
|
||||
>bar : Symbol(bar, Decl(controlFlowOptionalChain.ts, 161, 36))
|
||||
|
||||
o.bar;
|
||||
>o.bar : Symbol(bar, Decl(controlFlowOptionalChain.ts, 161, 36))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 316, 13))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 370, 13))
|
||||
>bar : Symbol(bar, Decl(controlFlowOptionalChain.ts, 161, 36))
|
||||
}
|
||||
if (o?.baz instanceof Error) {
|
||||
>o?.baz : Symbol(baz, Decl(controlFlowOptionalChain.ts, 161, 51))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 316, 13))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 370, 13))
|
||||
>baz : Symbol(baz, Decl(controlFlowOptionalChain.ts, 161, 51))
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
o.baz;
|
||||
>o.baz : Symbol(baz, Decl(controlFlowOptionalChain.ts, 161, 51))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 316, 13))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 370, 13))
|
||||
>baz : Symbol(baz, Decl(controlFlowOptionalChain.ts, 161, 51))
|
||||
}
|
||||
}
|
||||
|
||||
function f22(o: Thing | undefined) {
|
||||
>f22 : Symbol(f22, Decl(controlFlowOptionalChain.ts, 383, 1))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13))
|
||||
>Thing : Symbol(Thing, Decl(controlFlowOptionalChain.ts, 159, 1))
|
||||
|
||||
if (typeof o?.foo === "number") {
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
if (typeof o?.foo !== "number") {
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
o.foo; // Error
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
if (typeof o?.foo == "number") {
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
if (typeof o?.foo != "number") {
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
o.foo; // Error
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 385, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
}
|
||||
|
||||
function f23(o: Thing | undefined) {
|
||||
>f23 : Symbol(f23, Decl(controlFlowOptionalChain.ts, 410, 1))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13))
|
||||
>Thing : Symbol(Thing, Decl(controlFlowOptionalChain.ts, 159, 1))
|
||||
|
||||
if (typeof o?.foo === "undefined") {
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
o.foo; // Error
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
if (typeof o?.foo !== "undefined") {
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
if (typeof o?.foo == "undefined") {
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
o.foo; // Error
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
if (typeof o?.foo != "undefined") {
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 412, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
}
|
||||
|
||||
declare function assert(x: unknown): asserts x;
|
||||
>assert : Symbol(assert, Decl(controlFlowOptionalChain.ts, 437, 1))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 439, 24))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 439, 24))
|
||||
|
||||
declare function assertNonNull<T>(x: T): asserts x is NonNullable<T>;
|
||||
>assertNonNull : Symbol(assertNonNull, Decl(controlFlowOptionalChain.ts, 439, 47))
|
||||
>T : Symbol(T, Decl(controlFlowOptionalChain.ts, 440, 31))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 440, 34))
|
||||
>T : Symbol(T, Decl(controlFlowOptionalChain.ts, 440, 31))
|
||||
>x : Symbol(x, Decl(controlFlowOptionalChain.ts, 440, 34))
|
||||
>NonNullable : Symbol(NonNullable, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(controlFlowOptionalChain.ts, 440, 31))
|
||||
|
||||
function f30(o: Thing | undefined) {
|
||||
>f30 : Symbol(f30, Decl(controlFlowOptionalChain.ts, 440, 69))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 442, 13))
|
||||
>Thing : Symbol(Thing, Decl(controlFlowOptionalChain.ts, 159, 1))
|
||||
|
||||
if (!!true) {
|
||||
assert(o?.foo);
|
||||
>assert : Symbol(assert, Decl(controlFlowOptionalChain.ts, 437, 1))
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 442, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 442, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
if (!!true) {
|
||||
assert(o?.foo === 42);
|
||||
>assert : Symbol(assert, Decl(controlFlowOptionalChain.ts, 437, 1))
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 442, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 442, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
if (!!true) {
|
||||
assert(typeof o?.foo === "number");
|
||||
>assert : Symbol(assert, Decl(controlFlowOptionalChain.ts, 437, 1))
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 442, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 442, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
if (!!true) {
|
||||
assertNonNull(o?.foo);
|
||||
>assertNonNull : Symbol(assertNonNull, Decl(controlFlowOptionalChain.ts, 439, 47))
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 442, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 442, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
}
|
||||
}
|
||||
|
||||
function f40(o: Thing | undefined) {
|
||||
>f40 : Symbol(f40, Decl(controlFlowOptionalChain.ts, 459, 1))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 461, 13))
|
||||
>Thing : Symbol(Thing, Decl(controlFlowOptionalChain.ts, 159, 1))
|
||||
|
||||
switch (o?.foo) {
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 461, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
case "abc":
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 461, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
break;
|
||||
case 42:
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 461, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
break;
|
||||
case undefined:
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
o.foo; // Error
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 461, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
break;
|
||||
default:
|
||||
o.foo; // Error
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 461, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function f41(o: Thing | undefined) {
|
||||
>f41 : Symbol(f41, Decl(controlFlowOptionalChain.ts, 476, 1))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 478, 13))
|
||||
>Thing : Symbol(Thing, Decl(controlFlowOptionalChain.ts, 159, 1))
|
||||
|
||||
switch (typeof o?.foo) {
|
||||
>o?.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 478, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
case "string":
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 478, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
break;
|
||||
case "number":
|
||||
o.foo;
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 478, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
break;
|
||||
case "undefined":
|
||||
o.foo; // Error
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 478, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
break;
|
||||
default:
|
||||
o.foo; // Error
|
||||
>o.foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
>o : Symbol(o, Decl(controlFlowOptionalChain.ts, 478, 13))
|
||||
>foo : Symbol(foo, Decl(controlFlowOptionalChain.ts, 161, 14))
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Repros from #34570
|
||||
|
||||
type Shape =
|
||||
>Shape : Symbol(Shape, Decl(controlFlowOptionalChain.ts, 493, 1))
|
||||
|
||||
| { type: 'rectangle', width: number, height: number }
|
||||
>type : Symbol(type, Decl(controlFlowOptionalChain.ts, 498, 7))
|
||||
>width : Symbol(width, Decl(controlFlowOptionalChain.ts, 498, 26))
|
||||
>height : Symbol(height, Decl(controlFlowOptionalChain.ts, 498, 41))
|
||||
|
||||
| { type: 'circle', radius: number }
|
||||
>type : Symbol(type, Decl(controlFlowOptionalChain.ts, 499, 7))
|
||||
>radius : Symbol(radius, Decl(controlFlowOptionalChain.ts, 499, 23))
|
||||
|
||||
function getArea(shape?: Shape) {
|
||||
>getArea : Symbol(getArea, Decl(controlFlowOptionalChain.ts, 499, 40))
|
||||
>shape : Symbol(shape, Decl(controlFlowOptionalChain.ts, 501, 17))
|
||||
>Shape : Symbol(Shape, Decl(controlFlowOptionalChain.ts, 493, 1))
|
||||
|
||||
switch (shape?.type) {
|
||||
>shape?.type : Symbol(type, Decl(controlFlowOptionalChain.ts, 498, 7), Decl(controlFlowOptionalChain.ts, 499, 7))
|
||||
>shape : Symbol(shape, Decl(controlFlowOptionalChain.ts, 501, 17))
|
||||
>type : Symbol(type, Decl(controlFlowOptionalChain.ts, 498, 7), Decl(controlFlowOptionalChain.ts, 499, 7))
|
||||
|
||||
case 'circle':
|
||||
return Math.PI * shape.radius ** 2
|
||||
>Math.PI : Symbol(Math.PI, Decl(lib.es5.d.ts, --, --))
|
||||
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>PI : Symbol(Math.PI, Decl(lib.es5.d.ts, --, --))
|
||||
>shape.radius : Symbol(radius, Decl(controlFlowOptionalChain.ts, 499, 23))
|
||||
>shape : Symbol(shape, Decl(controlFlowOptionalChain.ts, 501, 17))
|
||||
>radius : Symbol(radius, Decl(controlFlowOptionalChain.ts, 499, 23))
|
||||
|
||||
case 'rectangle':
|
||||
return shape.width * shape.height
|
||||
>shape.width : Symbol(width, Decl(controlFlowOptionalChain.ts, 498, 26))
|
||||
>shape : Symbol(shape, Decl(controlFlowOptionalChain.ts, 501, 17))
|
||||
>width : Symbol(width, Decl(controlFlowOptionalChain.ts, 498, 26))
|
||||
>shape.height : Symbol(height, Decl(controlFlowOptionalChain.ts, 498, 41))
|
||||
>shape : Symbol(shape, Decl(controlFlowOptionalChain.ts, 501, 17))
|
||||
>height : Symbol(height, Decl(controlFlowOptionalChain.ts, 498, 41))
|
||||
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
type Feature = {
|
||||
>Feature : Symbol(Feature, Decl(controlFlowOptionalChain.ts, 510, 1))
|
||||
|
||||
id: string;
|
||||
>id : Symbol(id, Decl(controlFlowOptionalChain.ts, 512, 16))
|
||||
|
||||
geometry?: {
|
||||
>geometry : Symbol(geometry, Decl(controlFlowOptionalChain.ts, 513, 13))
|
||||
|
||||
type: string;
|
||||
>type : Symbol(type, Decl(controlFlowOptionalChain.ts, 514, 14))
|
||||
|
||||
coordinates: number[];
|
||||
>coordinates : Symbol(coordinates, Decl(controlFlowOptionalChain.ts, 515, 17))
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
function extractCoordinates(f: Feature): number[] {
|
||||
>extractCoordinates : Symbol(extractCoordinates, Decl(controlFlowOptionalChain.ts, 518, 2))
|
||||
>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 521, 28))
|
||||
>Feature : Symbol(Feature, Decl(controlFlowOptionalChain.ts, 510, 1))
|
||||
|
||||
if (f.geometry?.type !== 'test') {
|
||||
>f.geometry?.type : Symbol(type, Decl(controlFlowOptionalChain.ts, 514, 14))
|
||||
>f.geometry : Symbol(geometry, Decl(controlFlowOptionalChain.ts, 513, 13))
|
||||
>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 521, 28))
|
||||
>geometry : Symbol(geometry, Decl(controlFlowOptionalChain.ts, 513, 13))
|
||||
>type : Symbol(type, Decl(controlFlowOptionalChain.ts, 514, 14))
|
||||
|
||||
return [];
|
||||
}
|
||||
return f.geometry.coordinates;
|
||||
>f.geometry.coordinates : Symbol(coordinates, Decl(controlFlowOptionalChain.ts, 515, 17))
|
||||
>f.geometry : Symbol(geometry, Decl(controlFlowOptionalChain.ts, 513, 13))
|
||||
>f : Symbol(f, Decl(controlFlowOptionalChain.ts, 521, 28))
|
||||
>geometry : Symbol(geometry, Decl(controlFlowOptionalChain.ts, 513, 13))
|
||||
>coordinates : Symbol(coordinates, Decl(controlFlowOptionalChain.ts, 515, 17))
|
||||
}
|
||||
|
||||
|
|
|
@ -1170,6 +1170,163 @@ function f14(o: Thing | null) {
|
|||
}
|
||||
}
|
||||
|
||||
function f15(o: Thing | undefined, value: number) {
|
||||
>f15 : (o: Thing | undefined, value: number) => void
|
||||
>o : Thing | undefined
|
||||
>value : number
|
||||
|
||||
if (o?.foo === value) {
|
||||
>o?.foo === value : boolean
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
>value : number
|
||||
|
||||
o.foo;
|
||||
>o.foo : number
|
||||
>o : Thing
|
||||
>foo : number
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
>o.foo : string | number
|
||||
>o : Thing | undefined
|
||||
>foo : string | number
|
||||
}
|
||||
if (o?.foo !== value) {
|
||||
>o?.foo !== value : boolean
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
>value : number
|
||||
|
||||
o.foo; // Error
|
||||
>o.foo : string | number
|
||||
>o : Thing | undefined
|
||||
>foo : string | number
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
>o.foo : number
|
||||
>o : Thing
|
||||
>foo : number
|
||||
}
|
||||
if (o?.foo == value) {
|
||||
>o?.foo == value : boolean
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
>value : number
|
||||
|
||||
o.foo;
|
||||
>o.foo : string | number
|
||||
>o : Thing
|
||||
>foo : string | number
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
>o.foo : string | number
|
||||
>o : Thing | undefined
|
||||
>foo : string | number
|
||||
}
|
||||
if (o?.foo != value) {
|
||||
>o?.foo != value : boolean
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
>value : number
|
||||
|
||||
o.foo; // Error
|
||||
>o.foo : string | number
|
||||
>o : Thing | undefined
|
||||
>foo : string | number
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
>o.foo : number
|
||||
>o : Thing
|
||||
>foo : number
|
||||
}
|
||||
}
|
||||
|
||||
function f16(o: Thing | undefined) {
|
||||
>f16 : (o: Thing | undefined) => void
|
||||
>o : Thing | undefined
|
||||
|
||||
if (o?.foo === undefined) {
|
||||
>o?.foo === undefined : boolean
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
>undefined : undefined
|
||||
|
||||
o.foo; // Error
|
||||
>o.foo : never
|
||||
>o : Thing | undefined
|
||||
>foo : never
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
>o.foo : string | number
|
||||
>o : Thing
|
||||
>foo : string | number
|
||||
}
|
||||
if (o?.foo !== undefined) {
|
||||
>o?.foo !== undefined : boolean
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
>undefined : undefined
|
||||
|
||||
o.foo;
|
||||
>o.foo : string | number
|
||||
>o : Thing
|
||||
>foo : string | number
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
>o.foo : never
|
||||
>o : Thing | undefined
|
||||
>foo : never
|
||||
}
|
||||
if (o?.foo == undefined) {
|
||||
>o?.foo == undefined : boolean
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
>undefined : undefined
|
||||
|
||||
o.foo; // Error
|
||||
>o.foo : never
|
||||
>o : Thing | undefined
|
||||
>foo : never
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
>o.foo : string | number
|
||||
>o : Thing
|
||||
>foo : string | number
|
||||
}
|
||||
if (o?.foo != undefined) {
|
||||
>o?.foo != undefined : boolean
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
>undefined : undefined
|
||||
|
||||
o.foo;
|
||||
>o.foo : string | number
|
||||
>o : Thing
|
||||
>foo : string | number
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
>o.foo : never
|
||||
>o : Thing | undefined
|
||||
>foo : never
|
||||
}
|
||||
}
|
||||
|
||||
function f20(o: Thing | undefined) {
|
||||
>f20 : (o: Thing | undefined) => void
|
||||
>o : Thing | undefined
|
||||
|
@ -1287,3 +1444,445 @@ function f21(o: Thing | null) {
|
|||
}
|
||||
}
|
||||
|
||||
function f22(o: Thing | undefined) {
|
||||
>f22 : (o: Thing | undefined) => void
|
||||
>o : Thing | undefined
|
||||
|
||||
if (typeof o?.foo === "number") {
|
||||
>typeof o?.foo === "number" : boolean
|
||||
>typeof o?.foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
>"number" : "number"
|
||||
|
||||
o.foo;
|
||||
>o.foo : number
|
||||
>o : Thing
|
||||
>foo : number
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
>o.foo : string
|
||||
>o : Thing | undefined
|
||||
>foo : string
|
||||
}
|
||||
if (typeof o?.foo !== "number") {
|
||||
>typeof o?.foo !== "number" : boolean
|
||||
>typeof o?.foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
>"number" : "number"
|
||||
|
||||
o.foo; // Error
|
||||
>o.foo : string
|
||||
>o : Thing | undefined
|
||||
>foo : string
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
>o.foo : number
|
||||
>o : Thing
|
||||
>foo : number
|
||||
}
|
||||
if (typeof o?.foo == "number") {
|
||||
>typeof o?.foo == "number" : boolean
|
||||
>typeof o?.foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
>"number" : "number"
|
||||
|
||||
o.foo;
|
||||
>o.foo : number
|
||||
>o : Thing
|
||||
>foo : number
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
>o.foo : string
|
||||
>o : Thing | undefined
|
||||
>foo : string
|
||||
}
|
||||
if (typeof o?.foo != "number") {
|
||||
>typeof o?.foo != "number" : boolean
|
||||
>typeof o?.foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
>"number" : "number"
|
||||
|
||||
o.foo; // Error
|
||||
>o.foo : string
|
||||
>o : Thing | undefined
|
||||
>foo : string
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
>o.foo : number
|
||||
>o : Thing
|
||||
>foo : number
|
||||
}
|
||||
}
|
||||
|
||||
function f23(o: Thing | undefined) {
|
||||
>f23 : (o: Thing | undefined) => void
|
||||
>o : Thing | undefined
|
||||
|
||||
if (typeof o?.foo === "undefined") {
|
||||
>typeof o?.foo === "undefined" : boolean
|
||||
>typeof o?.foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
>"undefined" : "undefined"
|
||||
|
||||
o.foo; // Error
|
||||
>o.foo : never
|
||||
>o : Thing | undefined
|
||||
>foo : never
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
>o.foo : string | number
|
||||
>o : Thing
|
||||
>foo : string | number
|
||||
}
|
||||
if (typeof o?.foo !== "undefined") {
|
||||
>typeof o?.foo !== "undefined" : boolean
|
||||
>typeof o?.foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
>"undefined" : "undefined"
|
||||
|
||||
o.foo;
|
||||
>o.foo : string | number
|
||||
>o : Thing
|
||||
>foo : string | number
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
>o.foo : never
|
||||
>o : Thing | undefined
|
||||
>foo : never
|
||||
}
|
||||
if (typeof o?.foo == "undefined") {
|
||||
>typeof o?.foo == "undefined" : boolean
|
||||
>typeof o?.foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
>"undefined" : "undefined"
|
||||
|
||||
o.foo; // Error
|
||||
>o.foo : never
|
||||
>o : Thing | undefined
|
||||
>foo : never
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
>o.foo : string | number
|
||||
>o : Thing
|
||||
>foo : string | number
|
||||
}
|
||||
if (typeof o?.foo != "undefined") {
|
||||
>typeof o?.foo != "undefined" : boolean
|
||||
>typeof o?.foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
>"undefined" : "undefined"
|
||||
|
||||
o.foo;
|
||||
>o.foo : string | number
|
||||
>o : Thing
|
||||
>foo : string | number
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
>o.foo : never
|
||||
>o : Thing | undefined
|
||||
>foo : never
|
||||
}
|
||||
}
|
||||
|
||||
declare function assert(x: unknown): asserts x;
|
||||
>assert : (x: unknown) => asserts x
|
||||
>x : unknown
|
||||
|
||||
declare function assertNonNull<T>(x: T): asserts x is NonNullable<T>;
|
||||
>assertNonNull : <T>(x: T) => asserts x is NonNullable<T>
|
||||
>x : T
|
||||
|
||||
function f30(o: Thing | undefined) {
|
||||
>f30 : (o: Thing | undefined) => void
|
||||
>o : Thing | undefined
|
||||
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
assert(o?.foo);
|
||||
>assert(o?.foo) : void
|
||||
>assert : (x: unknown) => asserts x
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
|
||||
o.foo;
|
||||
>o.foo : string | number
|
||||
>o : Thing
|
||||
>foo : string | number
|
||||
}
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
assert(o?.foo === 42);
|
||||
>assert(o?.foo === 42) : void
|
||||
>assert : (x: unknown) => asserts x
|
||||
>o?.foo === 42 : boolean
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
>42 : 42
|
||||
|
||||
o.foo;
|
||||
>o.foo : 42
|
||||
>o : Thing
|
||||
>foo : 42
|
||||
}
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
assert(typeof o?.foo === "number");
|
||||
>assert(typeof o?.foo === "number") : void
|
||||
>assert : (x: unknown) => asserts x
|
||||
>typeof o?.foo === "number" : boolean
|
||||
>typeof o?.foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
>"number" : "number"
|
||||
|
||||
o.foo;
|
||||
>o.foo : number
|
||||
>o : Thing
|
||||
>foo : number
|
||||
}
|
||||
if (!!true) {
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
assertNonNull(o?.foo);
|
||||
>assertNonNull(o?.foo) : void
|
||||
>assertNonNull : <T>(x: T) => asserts x is NonNullable<T>
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
|
||||
o.foo;
|
||||
>o.foo : string | number
|
||||
>o : Thing
|
||||
>foo : string | number
|
||||
}
|
||||
}
|
||||
|
||||
function f40(o: Thing | undefined) {
|
||||
>f40 : (o: Thing | undefined) => void
|
||||
>o : Thing | undefined
|
||||
|
||||
switch (o?.foo) {
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
|
||||
case "abc":
|
||||
>"abc" : "abc"
|
||||
|
||||
o.foo;
|
||||
>o.foo : "abc"
|
||||
>o : Thing
|
||||
>foo : "abc"
|
||||
|
||||
break;
|
||||
case 42:
|
||||
>42 : 42
|
||||
|
||||
o.foo;
|
||||
>o.foo : 42
|
||||
>o : Thing
|
||||
>foo : 42
|
||||
|
||||
break;
|
||||
case undefined:
|
||||
>undefined : undefined
|
||||
|
||||
o.foo; // Error
|
||||
>o.foo : never
|
||||
>o : Thing | undefined
|
||||
>foo : never
|
||||
|
||||
break;
|
||||
default:
|
||||
o.foo; // Error
|
||||
>o.foo : string | number
|
||||
>o : Thing | undefined
|
||||
>foo : string | number
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function f41(o: Thing | undefined) {
|
||||
>f41 : (o: Thing | undefined) => void
|
||||
>o : Thing | undefined
|
||||
|
||||
switch (typeof o?.foo) {
|
||||
>typeof o?.foo : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
|
||||
>o?.foo : string | number | undefined
|
||||
>o : Thing | undefined
|
||||
>foo : string | number | undefined
|
||||
|
||||
case "string":
|
||||
>"string" : "string"
|
||||
|
||||
o.foo;
|
||||
>o.foo : string
|
||||
>o : Thing
|
||||
>foo : string
|
||||
|
||||
break;
|
||||
case "number":
|
||||
>"number" : "number"
|
||||
|
||||
o.foo;
|
||||
>o.foo : number
|
||||
>o : Thing
|
||||
>foo : number
|
||||
|
||||
break;
|
||||
case "undefined":
|
||||
>"undefined" : "undefined"
|
||||
|
||||
o.foo; // Error
|
||||
>o.foo : never
|
||||
>o : Thing | undefined
|
||||
>foo : never
|
||||
|
||||
break;
|
||||
default:
|
||||
o.foo; // Error
|
||||
>o.foo : never
|
||||
>o : Thing | undefined
|
||||
>foo : never
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Repros from #34570
|
||||
|
||||
type Shape =
|
||||
>Shape : Shape
|
||||
|
||||
| { type: 'rectangle', width: number, height: number }
|
||||
>type : "rectangle"
|
||||
>width : number
|
||||
>height : number
|
||||
|
||||
| { type: 'circle', radius: number }
|
||||
>type : "circle"
|
||||
>radius : number
|
||||
|
||||
function getArea(shape?: Shape) {
|
||||
>getArea : (shape?: { type: "rectangle"; width: number; height: number; } | { type: "circle"; radius: number; } | undefined) => number
|
||||
>shape : { type: "rectangle"; width: number; height: number; } | { type: "circle"; radius: number; } | undefined
|
||||
|
||||
switch (shape?.type) {
|
||||
>shape?.type : "rectangle" | "circle" | undefined
|
||||
>shape : { type: "rectangle"; width: number; height: number; } | { type: "circle"; radius: number; } | undefined
|
||||
>type : "rectangle" | "circle" | undefined
|
||||
|
||||
case 'circle':
|
||||
>'circle' : "circle"
|
||||
|
||||
return Math.PI * shape.radius ** 2
|
||||
>Math.PI * shape.radius ** 2 : number
|
||||
>Math.PI : number
|
||||
>Math : Math
|
||||
>PI : number
|
||||
>shape.radius ** 2 : number
|
||||
>shape.radius : number
|
||||
>shape : { type: "circle"; radius: number; }
|
||||
>radius : number
|
||||
>2 : 2
|
||||
|
||||
case 'rectangle':
|
||||
>'rectangle' : "rectangle"
|
||||
|
||||
return shape.width * shape.height
|
||||
>shape.width * shape.height : number
|
||||
>shape.width : number
|
||||
>shape : { type: "rectangle"; width: number; height: number; }
|
||||
>width : number
|
||||
>shape.height : number
|
||||
>shape : { type: "rectangle"; width: number; height: number; }
|
||||
>height : number
|
||||
|
||||
default:
|
||||
return 0
|
||||
>0 : 0
|
||||
}
|
||||
}
|
||||
|
||||
type Feature = {
|
||||
>Feature : Feature
|
||||
|
||||
id: string;
|
||||
>id : string
|
||||
|
||||
geometry?: {
|
||||
>geometry : { type: string; coordinates: number[]; } | undefined
|
||||
|
||||
type: string;
|
||||
>type : string
|
||||
|
||||
coordinates: number[];
|
||||
>coordinates : number[]
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
function extractCoordinates(f: Feature): number[] {
|
||||
>extractCoordinates : (f: Feature) => number[]
|
||||
>f : Feature
|
||||
|
||||
if (f.geometry?.type !== 'test') {
|
||||
>f.geometry?.type !== 'test' : boolean
|
||||
>f.geometry?.type : string | undefined
|
||||
>f.geometry : { type: string; coordinates: number[]; } | undefined
|
||||
>f : Feature
|
||||
>geometry : { type: string; coordinates: number[]; } | undefined
|
||||
>type : string | undefined
|
||||
>'test' : "test"
|
||||
|
||||
return [];
|
||||
>[] : never[]
|
||||
}
|
||||
return f.geometry.coordinates;
|
||||
>f.geometry.coordinates : number[]
|
||||
>f.geometry : { type: string; coordinates: number[]; }
|
||||
>f : Feature
|
||||
>geometry : { type: string; coordinates: number[]; }
|
||||
>coordinates : number[]
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
tests/cases/conformance/salsa/main.js(2,13): error TS2339: Property 'foo' does not exist on type 'Alias'.
|
||||
tests/cases/conformance/salsa/main.js(4,9): error TS2339: Property 'foo' does not exist on type 'Alias'.
|
||||
tests/cases/conformance/salsa/main.js(3,13): error TS2339: Property 'func' does not exist on type 'Alias'.
|
||||
tests/cases/conformance/salsa/main.js(3,38): error TS2339: Property '_func' does not exist on type 'Alias'.
|
||||
tests/cases/conformance/salsa/main.js(5,9): error TS2339: Property 'foo' does not exist on type 'Alias'.
|
||||
tests/cases/conformance/salsa/main.js(6,9): error TS2339: Property 'func' does not exist on type 'Alias'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/salsa/mod1.js (0 errors) ====
|
||||
|
@ -8,13 +11,21 @@ tests/cases/conformance/salsa/main.js(4,9): error TS2339: Property 'foo' does no
|
|||
}
|
||||
module.exports = Alias;
|
||||
|
||||
==== tests/cases/conformance/salsa/main.js (2 errors) ====
|
||||
==== tests/cases/conformance/salsa/main.js (5 errors) ====
|
||||
import A from './mod1'
|
||||
A.prototype.foo = 0
|
||||
~~~
|
||||
!!! error TS2339: Property 'foo' does not exist on type 'Alias'.
|
||||
A.prototype.func = function() { this._func = 0; }
|
||||
~~~~
|
||||
!!! error TS2339: Property 'func' does not exist on type 'Alias'.
|
||||
~~~~~
|
||||
!!! error TS2339: Property '_func' does not exist on type 'Alias'.
|
||||
new A().bar
|
||||
new A().foo
|
||||
~~~
|
||||
!!! error TS2339: Property 'foo' does not exist on type 'Alias'.
|
||||
new A().func()
|
||||
~~~~
|
||||
!!! error TS2339: Property 'func' does not exist on type 'Alias'.
|
||||
|
|
@ -20,6 +20,12 @@ A.prototype.foo = 0
|
|||
>A : Symbol(A, Decl(main.js, 0, 6))
|
||||
>prototype : Symbol(A.prototype)
|
||||
|
||||
A.prototype.func = function() { this._func = 0; }
|
||||
>A.prototype : Symbol(A.prototype)
|
||||
>A : Symbol(A, Decl(main.js, 0, 6))
|
||||
>prototype : Symbol(A.prototype)
|
||||
>this : Symbol(A, Decl(mod1.js, 0, 0))
|
||||
|
||||
new A().bar
|
||||
>new A().bar : Symbol(A.bar, Decl(mod1.js, 0, 13))
|
||||
>A : Symbol(A, Decl(main.js, 0, 6))
|
||||
|
@ -28,3 +34,6 @@ new A().bar
|
|||
new A().foo
|
||||
>A : Symbol(A, Decl(main.js, 0, 6))
|
||||
|
||||
new A().func()
|
||||
>A : Symbol(A, Decl(main.js, 0, 6))
|
||||
|
||||
|
|
|
@ -26,6 +26,20 @@ A.prototype.foo = 0
|
|||
>foo : any
|
||||
>0 : 0
|
||||
|
||||
A.prototype.func = function() { this._func = 0; }
|
||||
>A.prototype.func = function() { this._func = 0; } : () => void
|
||||
>A.prototype.func : any
|
||||
>A.prototype : A
|
||||
>A : typeof A
|
||||
>prototype : A
|
||||
>func : any
|
||||
>function() { this._func = 0; } : () => void
|
||||
>this._func = 0 : 0
|
||||
>this._func : any
|
||||
>this : A
|
||||
>_func : any
|
||||
>0 : 0
|
||||
|
||||
new A().bar
|
||||
>new A().bar : () => number
|
||||
>new A() : A
|
||||
|
@ -38,3 +52,10 @@ new A().foo
|
|||
>A : typeof A
|
||||
>foo : any
|
||||
|
||||
new A().func()
|
||||
>new A().func() : any
|
||||
>new A().func : any
|
||||
>new A() : A
|
||||
>A : typeof A
|
||||
>func : any
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
=== /a.js ===
|
||||
function Graphic() {
|
||||
>Graphic : Symbol(Graphic, Decl(a.js, 0, 0))
|
||||
}
|
||||
|
||||
Object.defineProperty(Graphic.prototype, "instance", {
|
||||
>Object.defineProperty : Symbol(ObjectConstructor.defineProperty, Decl(lib.es5.d.ts, --, --))
|
||||
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>defineProperty : Symbol(ObjectConstructor.defineProperty, Decl(lib.es5.d.ts, --, --))
|
||||
>Graphic.prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --))
|
||||
>Graphic : Symbol(Graphic, Decl(a.js, 0, 0))
|
||||
>prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --))
|
||||
>"instance" : Symbol(Graphic.instance, Decl(a.js, 1, 1))
|
||||
|
||||
get: function() {
|
||||
>get : Symbol(get, Decl(a.js, 3, 54))
|
||||
|
||||
return this;
|
||||
>this : Symbol(Graphic, Decl(a.js, 0, 0))
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
=== /a.js ===
|
||||
function Graphic() {
|
||||
>Graphic : typeof Graphic
|
||||
}
|
||||
|
||||
Object.defineProperty(Graphic.prototype, "instance", {
|
||||
>Object.defineProperty(Graphic.prototype, "instance", { get: function() { return this; }}) : any
|
||||
>Object.defineProperty : (o: any, p: string | number | symbol, attributes: PropertyDescriptor & ThisType<any>) => any
|
||||
>Object : ObjectConstructor
|
||||
>defineProperty : (o: any, p: string | number | symbol, attributes: PropertyDescriptor & ThisType<any>) => any
|
||||
>Graphic.prototype : any
|
||||
>Graphic : typeof Graphic
|
||||
>prototype : any
|
||||
>"instance" : "instance"
|
||||
>{ get: function() { return this; }} : { get: () => this; }
|
||||
|
||||
get: function() {
|
||||
>get : () => this
|
||||
>function() { return this; } : () => this
|
||||
|
||||
return this;
|
||||
>this : this
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
/b.js(1,8): error TS1259: Module '"/a"' can only be default-imported using the 'esModuleInterop' flag
|
||||
|
||||
|
||||
==== /a.js (0 errors) ====
|
||||
// https://github.com/microsoft/TypeScript/issues/34481
|
||||
|
||||
|
||||
const alias = {};
|
||||
module.exports = alias;
|
||||
|
||||
==== /b.js (1 errors) ====
|
||||
import a from "./a";
|
||||
~
|
||||
!!! error TS1259: Module '"/a"' can only be default-imported using the 'esModuleInterop' flag
|
||||
!!! related TS2594 /a.js:5:1: This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag.
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
=== /a.js ===
|
||||
// https://github.com/microsoft/TypeScript/issues/34481
|
||||
|
||||
|
||||
const alias = {};
|
||||
>alias : Symbol(alias, Decl(a.js, 3, 5))
|
||||
|
||||
module.exports = alias;
|
||||
>module.exports : Symbol("/a", Decl(a.js, 0, 0))
|
||||
>module : Symbol(export=, Decl(a.js, 3, 17))
|
||||
>exports : Symbol(export=, Decl(a.js, 3, 17))
|
||||
>alias : Symbol(alias, Decl(a.js, 3, 5))
|
||||
|
||||
=== /b.js ===
|
||||
import a from "./a";
|
||||
>a : Symbol(a, Decl(b.js, 0, 6))
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
=== /a.js ===
|
||||
// https://github.com/microsoft/TypeScript/issues/34481
|
||||
|
||||
|
||||
const alias = {};
|
||||
>alias : {}
|
||||
>{} : {}
|
||||
|
||||
module.exports = alias;
|
||||
>module.exports = alias : {}
|
||||
>module.exports : {}
|
||||
>module : { "/a": {}; }
|
||||
>exports : {}
|
||||
>alias : {}
|
||||
|
||||
=== /b.js ===
|
||||
import a from "./a";
|
||||
>a : any
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
=== tests/cases/compiler/jsNegativeELementAccessNotBound.js ===
|
||||
var indexMap = {};
|
||||
>indexMap : Symbol(indexMap, Decl(jsNegativeELementAccessNotBound.js, 0, 3))
|
||||
|
||||
indexMap[-1] = 0;
|
||||
>indexMap : Symbol(indexMap, Decl(jsNegativeELementAccessNotBound.js, 0, 3))
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
=== tests/cases/compiler/jsNegativeELementAccessNotBound.js ===
|
||||
var indexMap = {};
|
||||
>indexMap : {}
|
||||
>{} : {}
|
||||
|
||||
indexMap[-1] = 0;
|
||||
>indexMap[-1] = 0 : 0
|
||||
>indexMap[-1] : any
|
||||
>indexMap : {}
|
||||
>-1 : -1
|
||||
>1 : 1
|
||||
>0 : 0
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
=== tests/cases/conformance/jsdoc/mod1.js ===
|
||||
class C {
|
||||
>C : Symbol(C, Decl(mod1.js, 0, 0))
|
||||
|
||||
s() { }
|
||||
>s : Symbol(C.s, Decl(mod1.js, 0, 9))
|
||||
}
|
||||
module.exports.C = C
|
||||
>module.exports.C : Symbol(C, Decl(mod1.js, 2, 1))
|
||||
>module.exports : Symbol(C, Decl(mod1.js, 2, 1))
|
||||
>module : Symbol(module, Decl(mod1.js, 2, 1))
|
||||
>exports : Symbol("tests/cases/conformance/jsdoc/mod1", Decl(mod1.js, 0, 0))
|
||||
>C : Symbol(C, Decl(mod1.js, 2, 1))
|
||||
>C : Symbol(C, Decl(mod1.js, 0, 0))
|
||||
|
||||
=== tests/cases/conformance/jsdoc/test.js ===
|
||||
/** @typedef {import('./mod1').C} X */
|
||||
/** @param {X} c */
|
||||
function demo(c) {
|
||||
>demo : Symbol(demo, Decl(test.js, 0, 0))
|
||||
>c : Symbol(c, Decl(test.js, 2, 14))
|
||||
|
||||
c.s
|
||||
>c.s : Symbol(C.s, Decl(mod1.js, 0, 9))
|
||||
>c : Symbol(c, Decl(test.js, 2, 14))
|
||||
>s : Symbol(C.s, Decl(mod1.js, 0, 9))
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
=== tests/cases/conformance/jsdoc/mod1.js ===
|
||||
class C {
|
||||
>C : C
|
||||
|
||||
s() { }
|
||||
>s : () => void
|
||||
}
|
||||
module.exports.C = C
|
||||
>module.exports.C = C : typeof C
|
||||
>module.exports.C : typeof C
|
||||
>module.exports : typeof import("tests/cases/conformance/jsdoc/mod1")
|
||||
>module : { "tests/cases/conformance/jsdoc/mod1": typeof import("tests/cases/conformance/jsdoc/mod1"); }
|
||||
>exports : typeof import("tests/cases/conformance/jsdoc/mod1")
|
||||
>C : typeof C
|
||||
>C : typeof C
|
||||
|
||||
=== tests/cases/conformance/jsdoc/test.js ===
|
||||
/** @typedef {import('./mod1').C} X */
|
||||
/** @param {X} c */
|
||||
function demo(c) {
|
||||
>demo : (c: C) => void
|
||||
>c : C
|
||||
|
||||
c.s
|
||||
>c.s : () => void
|
||||
>c : C
|
||||
>s : () => void
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
=== tests/cases/conformance/jsdoc/jsdocTypeReferenceToMergedClass.js ===
|
||||
// https://github.com/microsoft/TypeScript/issues/34685
|
||||
|
||||
var Workspace = {}
|
||||
>Workspace : Symbol(Workspace, Decl(jsdocTypeReferenceToMergedClass.js, 2, 3), Decl(jsdocTypeReferenceToMergedClass.js, 5, 20), Decl(jsdocTypeReferenceToMergedClass.js, 7, 37))
|
||||
|
||||
/** @type {Workspace.Project} */
|
||||
var p;
|
||||
>p : Symbol(p, Decl(jsdocTypeReferenceToMergedClass.js, 4, 3))
|
||||
|
||||
p.isServiceProject()
|
||||
>p.isServiceProject : Symbol(isServiceProject, Decl(jsdocTypeReferenceToMergedClass.js, 8, 31))
|
||||
>p : Symbol(p, Decl(jsdocTypeReferenceToMergedClass.js, 4, 3))
|
||||
>isServiceProject : Symbol(isServiceProject, Decl(jsdocTypeReferenceToMergedClass.js, 8, 31))
|
||||
|
||||
Workspace.Project = function wp() { }
|
||||
>Workspace.Project : Symbol(Workspace.Project, Decl(jsdocTypeReferenceToMergedClass.js, 5, 20), Decl(jsdocTypeReferenceToMergedClass.js, 8, 10))
|
||||
>Workspace : Symbol(Workspace, Decl(jsdocTypeReferenceToMergedClass.js, 2, 3), Decl(jsdocTypeReferenceToMergedClass.js, 5, 20), Decl(jsdocTypeReferenceToMergedClass.js, 7, 37))
|
||||
>Project : Symbol(Workspace.Project, Decl(jsdocTypeReferenceToMergedClass.js, 5, 20), Decl(jsdocTypeReferenceToMergedClass.js, 8, 10))
|
||||
>wp : Symbol(wp, Decl(jsdocTypeReferenceToMergedClass.js, 7, 19))
|
||||
|
||||
Workspace.Project.prototype = {
|
||||
>Workspace.Project.prototype : Symbol(Workspace.Project.prototype, Decl(jsdocTypeReferenceToMergedClass.js, 7, 37))
|
||||
>Workspace.Project : Symbol(Workspace.Project, Decl(jsdocTypeReferenceToMergedClass.js, 5, 20), Decl(jsdocTypeReferenceToMergedClass.js, 8, 10))
|
||||
>Workspace : Symbol(Workspace, Decl(jsdocTypeReferenceToMergedClass.js, 2, 3), Decl(jsdocTypeReferenceToMergedClass.js, 5, 20), Decl(jsdocTypeReferenceToMergedClass.js, 7, 37))
|
||||
>Project : Symbol(Workspace.Project, Decl(jsdocTypeReferenceToMergedClass.js, 5, 20), Decl(jsdocTypeReferenceToMergedClass.js, 8, 10))
|
||||
>prototype : Symbol(Workspace.Project.prototype, Decl(jsdocTypeReferenceToMergedClass.js, 7, 37))
|
||||
|
||||
isServiceProject() {}
|
||||
>isServiceProject : Symbol(isServiceProject, Decl(jsdocTypeReferenceToMergedClass.js, 8, 31))
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
=== tests/cases/conformance/jsdoc/jsdocTypeReferenceToMergedClass.js ===
|
||||
// https://github.com/microsoft/TypeScript/issues/34685
|
||||
|
||||
var Workspace = {}
|
||||
>Workspace : typeof Workspace
|
||||
>{} : {}
|
||||
|
||||
/** @type {Workspace.Project} */
|
||||
var p;
|
||||
>p : wp
|
||||
|
||||
p.isServiceProject()
|
||||
>p.isServiceProject() : void
|
||||
>p.isServiceProject : () => void
|
||||
>p : wp
|
||||
>isServiceProject : () => void
|
||||
|
||||
Workspace.Project = function wp() { }
|
||||
>Workspace.Project = function wp() { } : typeof wp
|
||||
>Workspace.Project : typeof wp
|
||||
>Workspace : typeof Workspace
|
||||
>Project : typeof wp
|
||||
>function wp() { } : typeof wp
|
||||
>wp : typeof wp
|
||||
|
||||
Workspace.Project.prototype = {
|
||||
>Workspace.Project.prototype = { isServiceProject() {}} : { isServiceProject(): void; }
|
||||
>Workspace.Project.prototype : { isServiceProject(): void; }
|
||||
>Workspace.Project : typeof wp
|
||||
>Workspace : typeof Workspace
|
||||
>Project : typeof wp
|
||||
>prototype : { isServiceProject(): void; }
|
||||
>{ isServiceProject() {}} : { isServiceProject(): void; }
|
||||
|
||||
isServiceProject() {}
|
||||
>isServiceProject : () => void
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
//// [mixedPropertyElementAccessAssignmentDeclaration.ts]
|
||||
// Should not crash: #34642
|
||||
var arr = [];
|
||||
arr[0].prop[2] = {};
|
||||
|
||||
|
||||
//// [mixedPropertyElementAccessAssignmentDeclaration.js]
|
||||
// Should not crash: #34642
|
||||
var arr = [];
|
||||
arr[0].prop[2] = {};
|
|
@ -0,0 +1,8 @@
|
|||
=== tests/cases/conformance/salsa/mixedPropertyElementAccessAssignmentDeclaration.ts ===
|
||||
// Should not crash: #34642
|
||||
var arr = [];
|
||||
>arr : Symbol(arr, Decl(mixedPropertyElementAccessAssignmentDeclaration.ts, 1, 3))
|
||||
|
||||
arr[0].prop[2] = {};
|
||||
>arr : Symbol(arr, Decl(mixedPropertyElementAccessAssignmentDeclaration.ts, 1, 3))
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
=== tests/cases/conformance/salsa/mixedPropertyElementAccessAssignmentDeclaration.ts ===
|
||||
// Should not crash: #34642
|
||||
var arr = [];
|
||||
>arr : any[]
|
||||
>[] : undefined[]
|
||||
|
||||
arr[0].prop[2] = {};
|
||||
>arr[0].prop[2] = {} : {}
|
||||
>arr[0].prop[2] : any
|
||||
>arr[0].prop : any
|
||||
>arr[0] : any
|
||||
>arr : any[]
|
||||
>0 : 0
|
||||
>prop : any
|
||||
>2 : 2
|
||||
>{} : {}
|
||||
|
|
@ -38,10 +38,36 @@ const cc4 = c4 ?? true;
|
|||
const dd1 = d1 ?? {b: 1};
|
||||
const dd2 = d2 ?? {b: 1};
|
||||
const dd3 = d3 ?? {b: 1};
|
||||
const dd4 = d4 ?? {b: 1};
|
||||
const dd4 = d4 ?? {b: 1};
|
||||
|
||||
// Repro from #34635
|
||||
|
||||
declare function foo(): void;
|
||||
|
||||
const maybeBool = false;
|
||||
|
||||
if (!(maybeBool ?? true)) {
|
||||
foo();
|
||||
}
|
||||
|
||||
if (maybeBool ?? true) {
|
||||
foo();
|
||||
}
|
||||
else {
|
||||
foo();
|
||||
}
|
||||
|
||||
if (false ?? true) {
|
||||
foo();
|
||||
}
|
||||
else {
|
||||
foo();
|
||||
}
|
||||
|
||||
|
||||
//// [nullishCoalescingOperator1.js]
|
||||
"use strict";
|
||||
var _a;
|
||||
var aa1 = (a1 !== null && a1 !== void 0 ? a1 : 'whatever');
|
||||
var aa2 = (a2 !== null && a2 !== void 0 ? a2 : 'whatever');
|
||||
var aa3 = (a3 !== null && a3 !== void 0 ? a3 : 'whatever');
|
||||
|
@ -58,3 +84,19 @@ var dd1 = (d1 !== null && d1 !== void 0 ? d1 : { b: 1 });
|
|||
var dd2 = (d2 !== null && d2 !== void 0 ? d2 : { b: 1 });
|
||||
var dd3 = (d3 !== null && d3 !== void 0 ? d3 : { b: 1 });
|
||||
var dd4 = (d4 !== null && d4 !== void 0 ? d4 : { b: 1 });
|
||||
var maybeBool = false;
|
||||
if (!((maybeBool !== null && maybeBool !== void 0 ? maybeBool : true))) {
|
||||
foo();
|
||||
}
|
||||
if ((maybeBool !== null && maybeBool !== void 0 ? maybeBool : true)) {
|
||||
foo();
|
||||
}
|
||||
else {
|
||||
foo();
|
||||
}
|
||||
if (_a = false, (_a !== null && _a !== void 0 ? _a : true)) {
|
||||
foo();
|
||||
}
|
||||
else {
|
||||
foo();
|
||||
}
|
||||
|
|
|
@ -123,3 +123,38 @@ const dd4 = d4 ?? {b: 1};
|
|||
>d4 : Symbol(d4, Decl(nullishCoalescingOperator1.ts, 19, 13))
|
||||
>b : Symbol(b, Decl(nullishCoalescingOperator1.ts, 39, 19))
|
||||
|
||||
// Repro from #34635
|
||||
|
||||
declare function foo(): void;
|
||||
>foo : Symbol(foo, Decl(nullishCoalescingOperator1.ts, 39, 25))
|
||||
|
||||
const maybeBool = false;
|
||||
>maybeBool : Symbol(maybeBool, Decl(nullishCoalescingOperator1.ts, 45, 5))
|
||||
|
||||
if (!(maybeBool ?? true)) {
|
||||
>maybeBool : Symbol(maybeBool, Decl(nullishCoalescingOperator1.ts, 45, 5))
|
||||
|
||||
foo();
|
||||
>foo : Symbol(foo, Decl(nullishCoalescingOperator1.ts, 39, 25))
|
||||
}
|
||||
|
||||
if (maybeBool ?? true) {
|
||||
>maybeBool : Symbol(maybeBool, Decl(nullishCoalescingOperator1.ts, 45, 5))
|
||||
|
||||
foo();
|
||||
>foo : Symbol(foo, Decl(nullishCoalescingOperator1.ts, 39, 25))
|
||||
}
|
||||
else {
|
||||
foo();
|
||||
>foo : Symbol(foo, Decl(nullishCoalescingOperator1.ts, 39, 25))
|
||||
}
|
||||
|
||||
if (false ?? true) {
|
||||
foo();
|
||||
>foo : Symbol(foo, Decl(nullishCoalescingOperator1.ts, 39, 25))
|
||||
}
|
||||
else {
|
||||
foo();
|
||||
>foo : Symbol(foo, Decl(nullishCoalescingOperator1.ts, 39, 25))
|
||||
}
|
||||
|
||||
|
|
|
@ -170,3 +170,54 @@ const dd4 = d4 ?? {b: 1};
|
|||
>b : number
|
||||
>1 : 1
|
||||
|
||||
// Repro from #34635
|
||||
|
||||
declare function foo(): void;
|
||||
>foo : () => void
|
||||
|
||||
const maybeBool = false;
|
||||
>maybeBool : false
|
||||
>false : false
|
||||
|
||||
if (!(maybeBool ?? true)) {
|
||||
>!(maybeBool ?? true) : true
|
||||
>(maybeBool ?? true) : false
|
||||
>maybeBool ?? true : false
|
||||
>maybeBool : false
|
||||
>true : true
|
||||
|
||||
foo();
|
||||
>foo() : void
|
||||
>foo : () => void
|
||||
}
|
||||
|
||||
if (maybeBool ?? true) {
|
||||
>maybeBool ?? true : false
|
||||
>maybeBool : false
|
||||
>true : true
|
||||
|
||||
foo();
|
||||
>foo() : void
|
||||
>foo : () => void
|
||||
}
|
||||
else {
|
||||
foo();
|
||||
>foo() : void
|
||||
>foo : () => void
|
||||
}
|
||||
|
||||
if (false ?? true) {
|
||||
>false ?? true : false
|
||||
>false : false
|
||||
>true : true
|
||||
|
||||
foo();
|
||||
>foo() : void
|
||||
>foo : () => void
|
||||
}
|
||||
else {
|
||||
foo();
|
||||
>foo() : void
|
||||
>foo : () => void
|
||||
}
|
||||
|
||||
|
|
|
@ -52,10 +52,43 @@ let y1 = foo1(sx); // string
|
|||
|
||||
let x2 = foo2(sa); // unknown
|
||||
let y2 = foo2(sx); // { extra: number }
|
||||
|
||||
// Repro from #33490
|
||||
|
||||
declare class Component<P> { props: P }
|
||||
|
||||
export type ComponentClass<P> = new (props: P) => Component<P>;
|
||||
export type FunctionComponent<P> = (props: P) => null;
|
||||
|
||||
export type ComponentType<P> = FunctionComponent<P> | ComponentClass<P>;
|
||||
|
||||
export interface RouteComponentProps { route: string }
|
||||
|
||||
declare function withRouter<
|
||||
P extends RouteComponentProps,
|
||||
C extends ComponentType<P>
|
||||
>(
|
||||
component: C & ComponentType<P>
|
||||
): ComponentClass<Omit<P, keyof RouteComponentProps>>;
|
||||
|
||||
interface Props extends RouteComponentProps { username: string }
|
||||
|
||||
declare const MyComponent: ComponentType<Props>;
|
||||
|
||||
withRouter(MyComponent);
|
||||
|
||||
// Repro from #33490
|
||||
|
||||
type AB<T> = { a: T } | { b: T };
|
||||
|
||||
// T & AB<U> normalizes to T & { a: U } | T & { b: U } below
|
||||
declare function foo<T, U>(obj: T & AB<U>): [T, U];
|
||||
declare let ab: AB<string>;
|
||||
|
||||
let z = foo(ab); // [AB<string>, string]
|
||||
|
||||
|
||||
//// [unionAndIntersectionInference3.js]
|
||||
"use strict";
|
||||
// Repro from #30720
|
||||
concatMaybe([1, 2, 3], 4);
|
||||
// Repros from #32247
|
||||
|
@ -70,3 +103,5 @@ let x1 = foo1(sa); // string
|
|||
let y1 = foo1(sx); // string
|
||||
let x2 = foo2(sa); // unknown
|
||||
let y2 = foo2(sx); // { extra: number }
|
||||
withRouter(MyComponent);
|
||||
let z = foo(ab); // [AB<string>, string]
|
||||
|
|
|
@ -205,3 +205,107 @@ let y2 = foo2(sx); // { extra: number }
|
|||
>foo2 : Symbol(foo2, Decl(unionAndIntersectionInference3.ts, 42, 57))
|
||||
>sx : Symbol(sx, Decl(unionAndIntersectionInference3.ts, 46, 11))
|
||||
|
||||
// Repro from #33490
|
||||
|
||||
declare class Component<P> { props: P }
|
||||
>Component : Symbol(Component, Decl(unionAndIntersectionInference3.ts, 52, 18))
|
||||
>P : Symbol(P, Decl(unionAndIntersectionInference3.ts, 56, 24))
|
||||
>props : Symbol(Component.props, Decl(unionAndIntersectionInference3.ts, 56, 28))
|
||||
>P : Symbol(P, Decl(unionAndIntersectionInference3.ts, 56, 24))
|
||||
|
||||
export type ComponentClass<P> = new (props: P) => Component<P>;
|
||||
>ComponentClass : Symbol(ComponentClass, Decl(unionAndIntersectionInference3.ts, 56, 39))
|
||||
>P : Symbol(P, Decl(unionAndIntersectionInference3.ts, 58, 27))
|
||||
>props : Symbol(props, Decl(unionAndIntersectionInference3.ts, 58, 37))
|
||||
>P : Symbol(P, Decl(unionAndIntersectionInference3.ts, 58, 27))
|
||||
>Component : Symbol(Component, Decl(unionAndIntersectionInference3.ts, 52, 18))
|
||||
>P : Symbol(P, Decl(unionAndIntersectionInference3.ts, 58, 27))
|
||||
|
||||
export type FunctionComponent<P> = (props: P) => null;
|
||||
>FunctionComponent : Symbol(FunctionComponent, Decl(unionAndIntersectionInference3.ts, 58, 63))
|
||||
>P : Symbol(P, Decl(unionAndIntersectionInference3.ts, 59, 30))
|
||||
>props : Symbol(props, Decl(unionAndIntersectionInference3.ts, 59, 36))
|
||||
>P : Symbol(P, Decl(unionAndIntersectionInference3.ts, 59, 30))
|
||||
|
||||
export type ComponentType<P> = FunctionComponent<P> | ComponentClass<P>;
|
||||
>ComponentType : Symbol(ComponentType, Decl(unionAndIntersectionInference3.ts, 59, 54))
|
||||
>P : Symbol(P, Decl(unionAndIntersectionInference3.ts, 61, 26))
|
||||
>FunctionComponent : Symbol(FunctionComponent, Decl(unionAndIntersectionInference3.ts, 58, 63))
|
||||
>P : Symbol(P, Decl(unionAndIntersectionInference3.ts, 61, 26))
|
||||
>ComponentClass : Symbol(ComponentClass, Decl(unionAndIntersectionInference3.ts, 56, 39))
|
||||
>P : Symbol(P, Decl(unionAndIntersectionInference3.ts, 61, 26))
|
||||
|
||||
export interface RouteComponentProps { route: string }
|
||||
>RouteComponentProps : Symbol(RouteComponentProps, Decl(unionAndIntersectionInference3.ts, 61, 72))
|
||||
>route : Symbol(RouteComponentProps.route, Decl(unionAndIntersectionInference3.ts, 63, 38))
|
||||
|
||||
declare function withRouter<
|
||||
>withRouter : Symbol(withRouter, Decl(unionAndIntersectionInference3.ts, 63, 54))
|
||||
|
||||
P extends RouteComponentProps,
|
||||
>P : Symbol(P, Decl(unionAndIntersectionInference3.ts, 65, 28))
|
||||
>RouteComponentProps : Symbol(RouteComponentProps, Decl(unionAndIntersectionInference3.ts, 61, 72))
|
||||
|
||||
C extends ComponentType<P>
|
||||
>C : Symbol(C, Decl(unionAndIntersectionInference3.ts, 66, 32))
|
||||
>ComponentType : Symbol(ComponentType, Decl(unionAndIntersectionInference3.ts, 59, 54))
|
||||
>P : Symbol(P, Decl(unionAndIntersectionInference3.ts, 65, 28))
|
||||
|
||||
>(
|
||||
component: C & ComponentType<P>
|
||||
>component : Symbol(component, Decl(unionAndIntersectionInference3.ts, 68, 2))
|
||||
>C : Symbol(C, Decl(unionAndIntersectionInference3.ts, 66, 32))
|
||||
>ComponentType : Symbol(ComponentType, Decl(unionAndIntersectionInference3.ts, 59, 54))
|
||||
>P : Symbol(P, Decl(unionAndIntersectionInference3.ts, 65, 28))
|
||||
|
||||
): ComponentClass<Omit<P, keyof RouteComponentProps>>;
|
||||
>ComponentClass : Symbol(ComponentClass, Decl(unionAndIntersectionInference3.ts, 56, 39))
|
||||
>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --))
|
||||
>P : Symbol(P, Decl(unionAndIntersectionInference3.ts, 65, 28))
|
||||
>RouteComponentProps : Symbol(RouteComponentProps, Decl(unionAndIntersectionInference3.ts, 61, 72))
|
||||
|
||||
interface Props extends RouteComponentProps { username: string }
|
||||
>Props : Symbol(Props, Decl(unionAndIntersectionInference3.ts, 70, 54))
|
||||
>RouteComponentProps : Symbol(RouteComponentProps, Decl(unionAndIntersectionInference3.ts, 61, 72))
|
||||
>username : Symbol(Props.username, Decl(unionAndIntersectionInference3.ts, 72, 45))
|
||||
|
||||
declare const MyComponent: ComponentType<Props>;
|
||||
>MyComponent : Symbol(MyComponent, Decl(unionAndIntersectionInference3.ts, 74, 13))
|
||||
>ComponentType : Symbol(ComponentType, Decl(unionAndIntersectionInference3.ts, 59, 54))
|
||||
>Props : Symbol(Props, Decl(unionAndIntersectionInference3.ts, 70, 54))
|
||||
|
||||
withRouter(MyComponent);
|
||||
>withRouter : Symbol(withRouter, Decl(unionAndIntersectionInference3.ts, 63, 54))
|
||||
>MyComponent : Symbol(MyComponent, Decl(unionAndIntersectionInference3.ts, 74, 13))
|
||||
|
||||
// Repro from #33490
|
||||
|
||||
type AB<T> = { a: T } | { b: T };
|
||||
>AB : Symbol(AB, Decl(unionAndIntersectionInference3.ts, 76, 24))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 80, 8))
|
||||
>a : Symbol(a, Decl(unionAndIntersectionInference3.ts, 80, 14))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 80, 8))
|
||||
>b : Symbol(b, Decl(unionAndIntersectionInference3.ts, 80, 25))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 80, 8))
|
||||
|
||||
// T & AB<U> normalizes to T & { a: U } | T & { b: U } below
|
||||
declare function foo<T, U>(obj: T & AB<U>): [T, U];
|
||||
>foo : Symbol(foo, Decl(unionAndIntersectionInference3.ts, 80, 33))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 83, 21))
|
||||
>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 83, 23))
|
||||
>obj : Symbol(obj, Decl(unionAndIntersectionInference3.ts, 83, 27))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 83, 21))
|
||||
>AB : Symbol(AB, Decl(unionAndIntersectionInference3.ts, 76, 24))
|
||||
>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 83, 23))
|
||||
>T : Symbol(T, Decl(unionAndIntersectionInference3.ts, 83, 21))
|
||||
>U : Symbol(U, Decl(unionAndIntersectionInference3.ts, 83, 23))
|
||||
|
||||
declare let ab: AB<string>;
|
||||
>ab : Symbol(ab, Decl(unionAndIntersectionInference3.ts, 84, 11))
|
||||
>AB : Symbol(AB, Decl(unionAndIntersectionInference3.ts, 76, 24))
|
||||
|
||||
let z = foo(ab); // [AB<string>, string]
|
||||
>z : Symbol(z, Decl(unionAndIntersectionInference3.ts, 86, 3))
|
||||
>foo : Symbol(foo, Decl(unionAndIntersectionInference3.ts, 80, 33))
|
||||
>ab : Symbol(ab, Decl(unionAndIntersectionInference3.ts, 84, 11))
|
||||
|
||||
|
|
|
@ -135,3 +135,67 @@ let y2 = foo2(sx); // { extra: number }
|
|||
>foo2 : <T>(obj: string[] & T) => T
|
||||
>sx : string[] & { extra: number; }
|
||||
|
||||
// Repro from #33490
|
||||
|
||||
declare class Component<P> { props: P }
|
||||
>Component : Component<P>
|
||||
>props : P
|
||||
|
||||
export type ComponentClass<P> = new (props: P) => Component<P>;
|
||||
>ComponentClass : ComponentClass<P>
|
||||
>props : P
|
||||
|
||||
export type FunctionComponent<P> = (props: P) => null;
|
||||
>FunctionComponent : FunctionComponent<P>
|
||||
>props : P
|
||||
>null : null
|
||||
|
||||
export type ComponentType<P> = FunctionComponent<P> | ComponentClass<P>;
|
||||
>ComponentType : ComponentType<P>
|
||||
|
||||
export interface RouteComponentProps { route: string }
|
||||
>route : string
|
||||
|
||||
declare function withRouter<
|
||||
>withRouter : <P extends RouteComponentProps, C extends ComponentType<P>>(component: (C & FunctionComponent<P>) | (C & ComponentClass<P>)) => ComponentClass<Pick<P, Exclude<keyof P, "route">>>
|
||||
|
||||
P extends RouteComponentProps,
|
||||
C extends ComponentType<P>
|
||||
>(
|
||||
component: C & ComponentType<P>
|
||||
>component : (C & FunctionComponent<P>) | (C & ComponentClass<P>)
|
||||
|
||||
): ComponentClass<Omit<P, keyof RouteComponentProps>>;
|
||||
|
||||
interface Props extends RouteComponentProps { username: string }
|
||||
>username : string
|
||||
|
||||
declare const MyComponent: ComponentType<Props>;
|
||||
>MyComponent : ComponentType<Props>
|
||||
|
||||
withRouter(MyComponent);
|
||||
>withRouter(MyComponent) : ComponentClass<Pick<Props, "username">>
|
||||
>withRouter : <P extends RouteComponentProps, C extends ComponentType<P>>(component: (C & FunctionComponent<P>) | (C & ComponentClass<P>)) => ComponentClass<Pick<P, Exclude<keyof P, "route">>>
|
||||
>MyComponent : ComponentType<Props>
|
||||
|
||||
// Repro from #33490
|
||||
|
||||
type AB<T> = { a: T } | { b: T };
|
||||
>AB : AB<T>
|
||||
>a : T
|
||||
>b : T
|
||||
|
||||
// T & AB<U> normalizes to T & { a: U } | T & { b: U } below
|
||||
declare function foo<T, U>(obj: T & AB<U>): [T, U];
|
||||
>foo : <T, U>(obj: (T & { a: U; }) | (T & { b: U; })) => [T, U]
|
||||
>obj : (T & { a: U; }) | (T & { b: U; })
|
||||
|
||||
declare let ab: AB<string>;
|
||||
>ab : AB<string>
|
||||
|
||||
let z = foo(ab); // [AB<string>, string]
|
||||
>z : [AB<string>, string]
|
||||
>foo(ab) : [AB<string>, string]
|
||||
>foo : <T, U>(obj: (T & { a: U; }) | (T & { b: U; })) => [T, U]
|
||||
>ab : AB<string>
|
||||
|
||||
|
|
34
tests/cases/compiler/anonClassDeclarationEmitIsAnon.ts
Normal file
34
tests/cases/compiler/anonClassDeclarationEmitIsAnon.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
// @declaration: true
|
||||
// @filename: wrapClass.ts
|
||||
export function wrapClass(param: any) {
|
||||
return class Wrapped {
|
||||
foo() {
|
||||
return param;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type Constructor<T = {}> = new (...args: any[]) => T;
|
||||
|
||||
export function Timestamped<TBase extends Constructor>(Base: TBase) {
|
||||
return class extends Base {
|
||||
timestamp = Date.now();
|
||||
};
|
||||
}
|
||||
|
||||
// @filename: index.ts
|
||||
import { wrapClass, Timestamped } from "./wrapClass";
|
||||
|
||||
export default wrapClass(0);
|
||||
|
||||
// Simple class
|
||||
export class User {
|
||||
name = '';
|
||||
}
|
||||
|
||||
// User that is Timestamped
|
||||
export class TimestampedUser extends Timestamped(User) {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
// @allowJs: true
|
||||
// @checkJs: false
|
||||
// @noEmit: true
|
||||
// @Filename: /a.js
|
||||
|
||||
function Graphic() {
|
||||
}
|
||||
|
||||
Object.defineProperty(Graphic.prototype, "instance", {
|
||||
get: function() {
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
12
tests/cases/compiler/javascriptImportDefaultBadExport.ts
Normal file
12
tests/cases/compiler/javascriptImportDefaultBadExport.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
// https://github.com/microsoft/TypeScript/issues/34481
|
||||
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
|
||||
// @Filename: /a.js
|
||||
const alias = {};
|
||||
module.exports = alias;
|
||||
|
||||
// @Filename: /b.js
|
||||
import a from "./a";
|
6
tests/cases/compiler/jsNegativeElementAccessNotBound.ts
Normal file
6
tests/cases/compiler/jsNegativeElementAccessNotBound.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
// @filename: jsNegativeELementAccessNotBound.js
|
||||
var indexMap = {};
|
||||
indexMap[-1] = 0;
|
|
@ -302,6 +302,60 @@ function f14(o: Thing | null) {
|
|||
}
|
||||
}
|
||||
|
||||
function f15(o: Thing | undefined, value: number) {
|
||||
if (o?.foo === value) {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
if (o?.foo !== value) {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (o?.foo == value) {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
if (o?.foo != value) {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
}
|
||||
|
||||
function f16(o: Thing | undefined) {
|
||||
if (o?.foo === undefined) {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (o?.foo !== undefined) {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
if (o?.foo == undefined) {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (o?.foo != undefined) {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
}
|
||||
|
||||
function f20(o: Thing | undefined) {
|
||||
if (typeof o?.foo === "number") {
|
||||
o.foo;
|
||||
|
@ -331,3 +385,146 @@ function f21(o: Thing | null) {
|
|||
o.baz;
|
||||
}
|
||||
}
|
||||
|
||||
function f22(o: Thing | undefined) {
|
||||
if (typeof o?.foo === "number") {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
if (typeof o?.foo !== "number") {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (typeof o?.foo == "number") {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
if (typeof o?.foo != "number") {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
}
|
||||
|
||||
function f23(o: Thing | undefined) {
|
||||
if (typeof o?.foo === "undefined") {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (typeof o?.foo !== "undefined") {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
if (typeof o?.foo == "undefined") {
|
||||
o.foo; // Error
|
||||
}
|
||||
else {
|
||||
o.foo;
|
||||
}
|
||||
if (typeof o?.foo != "undefined") {
|
||||
o.foo;
|
||||
}
|
||||
else {
|
||||
o.foo; // Error
|
||||
}
|
||||
}
|
||||
|
||||
declare function assert(x: unknown): asserts x;
|
||||
declare function assertNonNull<T>(x: T): asserts x is NonNullable<T>;
|
||||
|
||||
function f30(o: Thing | undefined) {
|
||||
if (!!true) {
|
||||
assert(o?.foo);
|
||||
o.foo;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(o?.foo === 42);
|
||||
o.foo;
|
||||
}
|
||||
if (!!true) {
|
||||
assert(typeof o?.foo === "number");
|
||||
o.foo;
|
||||
}
|
||||
if (!!true) {
|
||||
assertNonNull(o?.foo);
|
||||
o.foo;
|
||||
}
|
||||
}
|
||||
|
||||
function f40(o: Thing | undefined) {
|
||||
switch (o?.foo) {
|
||||
case "abc":
|
||||
o.foo;
|
||||
break;
|
||||
case 42:
|
||||
o.foo;
|
||||
break;
|
||||
case undefined:
|
||||
o.foo; // Error
|
||||
break;
|
||||
default:
|
||||
o.foo; // Error
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function f41(o: Thing | undefined) {
|
||||
switch (typeof o?.foo) {
|
||||
case "string":
|
||||
o.foo;
|
||||
break;
|
||||
case "number":
|
||||
o.foo;
|
||||
break;
|
||||
case "undefined":
|
||||
o.foo; // Error
|
||||
break;
|
||||
default:
|
||||
o.foo; // Error
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Repros from #34570
|
||||
|
||||
type Shape =
|
||||
| { type: 'rectangle', width: number, height: number }
|
||||
| { type: 'circle', radius: number }
|
||||
|
||||
function getArea(shape?: Shape) {
|
||||
switch (shape?.type) {
|
||||
case 'circle':
|
||||
return Math.PI * shape.radius ** 2
|
||||
case 'rectangle':
|
||||
return shape.width * shape.height
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
type Feature = {
|
||||
id: string;
|
||||
geometry?: {
|
||||
type: string;
|
||||
coordinates: number[];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
function extractCoordinates(f: Feature): number[] {
|
||||
if (f.geometry?.type !== 'test') {
|
||||
return [];
|
||||
}
|
||||
return f.geometry.coordinates;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// @strict: true
|
||||
// @allowUnreachableCode: false
|
||||
|
||||
declare const a1: string | undefined | null
|
||||
declare const a2: string | undefined | null
|
||||
|
@ -39,4 +40,28 @@ const cc4 = c4 ?? true;
|
|||
const dd1 = d1 ?? {b: 1};
|
||||
const dd2 = d2 ?? {b: 1};
|
||||
const dd3 = d3 ?? {b: 1};
|
||||
const dd4 = d4 ?? {b: 1};
|
||||
const dd4 = d4 ?? {b: 1};
|
||||
|
||||
// Repro from #34635
|
||||
|
||||
declare function foo(): void;
|
||||
|
||||
const maybeBool = false;
|
||||
|
||||
if (!(maybeBool ?? true)) {
|
||||
foo();
|
||||
}
|
||||
|
||||
if (maybeBool ?? true) {
|
||||
foo();
|
||||
}
|
||||
else {
|
||||
foo();
|
||||
}
|
||||
|
||||
if (false ?? true) {
|
||||
foo();
|
||||
}
|
||||
else {
|
||||
foo();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @noEmit: true
|
||||
// @Filename: callOfPropertylessConstructorFunction.js
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
function Dependency(j) {
|
||||
return j
|
||||
}
|
||||
Dependency({})
|
|
@ -0,0 +1,15 @@
|
|||
// @allowJS: true
|
||||
// @suppressOutputPathCheck: true
|
||||
|
||||
// @filename: 0.js
|
||||
// @ts-check
|
||||
|
||||
var exports = {};
|
||||
|
||||
/**
|
||||
* @typedef {string}
|
||||
*/
|
||||
exports.SomeName;
|
||||
|
||||
/** @type {exports.SomeName} */
|
||||
const myString = 'str';
|
|
@ -0,0 +1,15 @@
|
|||
// @noEmit: true
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @Filename: mod1.js
|
||||
class C {
|
||||
s() { }
|
||||
}
|
||||
module.exports.C = C
|
||||
|
||||
// @Filename: test.js
|
||||
/** @typedef {import('./mod1').C} X */
|
||||
/** @param {X} c */
|
||||
function demo(c) {
|
||||
c.s
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// https://github.com/microsoft/TypeScript/issues/34685
|
||||
// @noEmit: true
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
|
||||
// @Filename: jsdocTypeReferenceToMergedClass.js
|
||||
var Workspace = {}
|
||||
/** @type {Workspace.Project} */
|
||||
var p;
|
||||
p.isServiceProject()
|
||||
|
||||
Workspace.Project = function wp() { }
|
||||
Workspace.Project.prototype = {
|
||||
isServiceProject() {}
|
||||
}
|
|
@ -11,5 +11,7 @@ module.exports = Alias;
|
|||
// @filename: main.js
|
||||
import A from './mod1'
|
||||
A.prototype.foo = 0
|
||||
A.prototype.func = function() { this._func = 0; }
|
||||
new A().bar
|
||||
new A().foo
|
||||
new A().func()
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
// Should not crash: #34642
|
||||
var arr = [];
|
||||
arr[0].prop[2] = {};
|
|
@ -54,3 +54,37 @@ let y1 = foo1(sx); // string
|
|||
|
||||
let x2 = foo2(sa); // unknown
|
||||
let y2 = foo2(sx); // { extra: number }
|
||||
|
||||
// Repro from #33490
|
||||
|
||||
declare class Component<P> { props: P }
|
||||
|
||||
export type ComponentClass<P> = new (props: P) => Component<P>;
|
||||
export type FunctionComponent<P> = (props: P) => null;
|
||||
|
||||
export type ComponentType<P> = FunctionComponent<P> | ComponentClass<P>;
|
||||
|
||||
export interface RouteComponentProps { route: string }
|
||||
|
||||
declare function withRouter<
|
||||
P extends RouteComponentProps,
|
||||
C extends ComponentType<P>
|
||||
>(
|
||||
component: C & ComponentType<P>
|
||||
): ComponentClass<Omit<P, keyof RouteComponentProps>>;
|
||||
|
||||
interface Props extends RouteComponentProps { username: string }
|
||||
|
||||
declare const MyComponent: ComponentType<Props>;
|
||||
|
||||
withRouter(MyComponent);
|
||||
|
||||
// Repro from #33490
|
||||
|
||||
type AB<T> = { a: T } | { b: T };
|
||||
|
||||
// T & AB<U> normalizes to T & { a: U } | T & { b: U } below
|
||||
declare function foo<T, U>(obj: T & AB<U>): [T, U];
|
||||
declare let ab: AB<string>;
|
||||
|
||||
let z = foo(ab); // [AB<string>, string]
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/// <reference path="fourslash.ts" />
|
||||
// @strict: true
|
||||
|
||||
//// interface User {
|
||||
//// address?: {
|
||||
//// city: string;
|
||||
//// "postal code": string;
|
||||
//// }
|
||||
//// };
|
||||
//// declare const user: User;
|
||||
//// user.address[|./**/|]
|
||||
|
||||
verify.completions({
|
||||
marker: "",
|
||||
exact: [],
|
||||
preferences: {
|
||||
includeInsertTextCompletions: true,
|
||||
includeAutomaticOptionalChainCompletions: false
|
||||
},
|
||||
});
|
|
@ -0,0 +1,8 @@
|
|||
/// <reference path='fourslash.ts' />
|
||||
// @noLib: true
|
||||
|
||||
////[|this|];
|
||||
////export const c = 1;
|
||||
|
||||
const [glob] = test.ranges();
|
||||
verify.referenceGroups(glob, undefined);
|
|
@ -583,6 +583,7 @@ declare namespace FourSlashInterface {
|
|||
readonly quotePreference?: "double" | "single";
|
||||
readonly includeCompletionsForModuleExports?: boolean;
|
||||
readonly includeInsertTextCompletions?: boolean;
|
||||
readonly includeAutomaticOptionalChainCompletions?: boolean;
|
||||
readonly importModuleSpecifierPreference?: "relative" | "non-relative";
|
||||
readonly importModuleSpecifierEnding?: "minimal" | "index" | "js";
|
||||
}
|
||||
|
|
57
tests/cases/fourslash/navigationBarComputedPropertyName.ts
Normal file
57
tests/cases/fourslash/navigationBarComputedPropertyName.ts
Normal file
|
@ -0,0 +1,57 @@
|
|||
/// <reference path="fourslash.ts"/>
|
||||
|
||||
////function F(key, value) {
|
||||
//// return {
|
||||
//// [key]: value,
|
||||
//// "prop": true
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.navigationTree({
|
||||
"text": "<global>",
|
||||
"kind": "script",
|
||||
"childItems": [
|
||||
{
|
||||
"text": "F",
|
||||
"kind": "function",
|
||||
"childItems": [
|
||||
{
|
||||
"text": "[key]",
|
||||
"kind": "property"
|
||||
},
|
||||
{
|
||||
"text": "\"prop\"",
|
||||
"kind": "property"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
verify.navigationBar([
|
||||
{
|
||||
"text": "<global>",
|
||||
"kind": "script",
|
||||
"childItems": [
|
||||
{
|
||||
"text": "F",
|
||||
"kind": "function"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "F",
|
||||
"kind": "function",
|
||||
"childItems": [
|
||||
{
|
||||
"text": "[key]",
|
||||
"kind": "property"
|
||||
},
|
||||
{
|
||||
"text": "\"prop\"",
|
||||
"kind": "property"
|
||||
}
|
||||
],
|
||||
"indent": 1
|
||||
}
|
||||
]);
|
Loading…
Reference in a new issue