Merge branch 'master' of https://github.com/Microsoft/TypeScript into feature/eslint

This commit is contained in:
Alexander T 2019-06-27 11:51:20 +03:00
commit 810303542d
48 changed files with 2484 additions and 1928 deletions

View file

@ -418,6 +418,7 @@ task("runtests-parallel").flags = {
" --workers=<number>": "The number of parallel workers to use.",
" --timeout=<ms>": "Overrides the default test timeout.",
" --built": "Compile using the built version of the compiler.",
" --skipPercent=<number>": "Skip expensive tests with <percent> chance to miss an edit. Default 5%.",
};
task("diff", () => exec(getDiffTool(), [refBaseline, localBaseline], { ignoreExitCode: true }));

View file

@ -87,6 +87,7 @@
"prex": "^0.4.3",
"q": "latest",
"remove-internal": "^2.9.2",
"simple-git": "^1.113.0",
"source-map-support": "latest",
"through2": "latest",
"travis-fold": "latest",
@ -106,7 +107,8 @@
"gulp": "gulp",
"jake": "gulp",
"lint": "gulp lint",
"setup-hooks": "node scripts/link-hooks.js"
"setup-hooks": "node scripts/link-hooks.js",
"update-costly-tests": "node scripts/costly-tests.js"
},
"browser": {
"fs": false,

View file

@ -14,6 +14,7 @@ module.exports = minimist(process.argv.slice(2), {
"ru": "runners", "runner": "runners",
"r": "reporter",
"c": "colors", "color": "colors",
"skip-percent": "skipPercent",
"w": "workers",
"f": "fix"
},
@ -69,4 +70,4 @@ if (module.exports.built) {
*
* @typedef {import("minimist").ParsedArgs & TypedOptions} CommandLineOptions
*/
void 0;
void 0;

View file

@ -31,6 +31,7 @@ async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode,
const inspect = cmdLineOptions.inspect;
const runners = cmdLineOptions.runners;
const light = cmdLineOptions.light;
const skipPercent = process.env.CI === "true" ? 0 : cmdLineOptions.skipPercent;
const stackTraceLimit = cmdLineOptions.stackTraceLimit;
const testConfigFile = "test.config";
const failed = cmdLineOptions.failed;
@ -62,8 +63,8 @@ async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode,
testTimeout = 400000;
}
if (tests || runners || light || testTimeout || taskConfigsFolder || keepFailed) {
writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, testTimeout, keepFailed);
if (tests || runners || light || testTimeout || taskConfigsFolder || keepFailed || skipPercent !== undefined) {
writeTestConfigFile(tests, runners, light, skipPercent, taskConfigsFolder, workerCount, stackTraceLimit, testTimeout, keepFailed);
}
const colors = cmdLineOptions.colors;
@ -158,17 +159,19 @@ exports.cleanTestDirs = cleanTestDirs;
* @param {string} tests
* @param {string} runners
* @param {boolean} light
* @param {string} skipPercent
* @param {string} [taskConfigsFolder]
* @param {string | number} [workerCount]
* @param {string} [stackTraceLimit]
* @param {string | number} [timeout]
* @param {boolean} [keepFailed]
*/
function writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, timeout, keepFailed) {
function writeTestConfigFile(tests, runners, light, skipPercent, taskConfigsFolder, workerCount, stackTraceLimit, timeout, keepFailed) {
const testConfigContents = JSON.stringify({
test: tests ? [tests] : undefined,
runners: runners ? runners.split(",") : undefined,
light,
skipPercent,
workerCount,
stackTraceLimit,
taskConfigsFolder,

103
scripts/costly-tests.js Normal file
View file

@ -0,0 +1,103 @@
// @ts-check
const fs = require("fs");
const git = require('simple-git/promise')('.')
const readline = require('readline')
/** @typedef {{ [s: string]: number}} Histogram */
async function main() {
/** @type {Histogram} */
const edits = Object.create(null)
/** @type {Histogram} */
const perf = JSON.parse(fs.readFileSync('.parallelperf.json', 'utf8'))
await collectCommits(git, "release-2.3", "master", /*author*/ undefined, files => fillMap(files, edits))
const totalTime = Object.values(perf).reduce((n,m) => n + m, 0)
const untouched = Object.values(perf).length - Object.values(edits).length
const totalEdits = Object.values(edits).reduce((n,m) => n + m, 0) + untouched + Object.values(edits).length
let i = 0
/** @type {{ name: string, time: number, edits: number, cost: number }[]} */
let data = []
for (const k in perf) {
const otherk = k.replace(/tsrunner-[a-z-]+?:\/\//, '')
const percentTime = perf[k] / totalTime
const percentHits = (1 + (edits[otherk] || 0)) / totalEdits
const cost = 5 + Math.log(percentTime / percentHits)
data.push({ name: otherk, time: perf[k], edits: 1 + (edits[otherk] || 0), cost})
if (edits[otherk])
i++
}
const output = {
totalTime,
totalEdits,
data: data.sort((x,y) => y.cost - x.cost).map(x => ({ ...x, cost: x.cost.toFixed(2) }))
}
fs.writeFileSync('tests/.test-cost.json', JSON.stringify(output), 'utf8')
}
main().catch(e => {
console.log(e);
process.exit(1);
})
/**
* @param {string[]} files
* @param {Histogram} histogram
*/
function fillMap(files, histogram) {
// keep edits to test cases (but not /users), and not file moves
const tests = files.filter(f => f.startsWith('tests/cases/') && !f.startsWith('tests/cases/user') && !/=>/.test(f))
for (const test of tests) {
histogram[test] = (histogram[test] || 0) + 1
}
}
/**
* @param {string} s
*/
function isSquashMergeMessage(s) {
return /\(#[0-9]+\)$/.test(s)
}
/**
* @param {string} s
*/
function isMergeCommit(s) {
return /Merge pull request #[0-9]+/.test(s)
}
/**
* @param {string} s
*/
function parseFiles(s) {
const lines = s.split('\n')
// Note that slice(2) only works for merge commits, which have an empty newline after the title
return lines.slice(2, lines.length - 2).map(line => line.split("|")[0].trim())
}
/**
* @param {import('simple-git/promise').SimpleGit} git
* @param {string} from
* @param {string} to
* @param {string | undefined} author - only include commits from this author
* @param {(files: string[]) => void} update
*/
async function collectCommits(git, from, to, author, update) {
let i = 0
for (const commit of (await git.log({ from, to })).all) {
i++
if ((!author || commit.author_name === author) && isMergeCommit(commit.message) || isSquashMergeMessage(commit.message)) {
readline.clearLine(process.stdout, /*left*/ -1)
readline.cursorTo(process.stdout, 0)
process.stdout.write(i + ": " + commit.date)
const files = parseFiles(await git.show([commit.hash, "--stat=1000,960,40", "--pretty=oneline"]))
update(files)
}
}
}

View file

@ -18,7 +18,7 @@ async function main() {
if (!prnums.length) {
return; // No enlisted PRs, nothing to update
}
if (!prnums.some(n => n === triggeredPR)) {
if (triggeredPR && !prnums.some(n => n === triggeredPR)) {
return; // Only have work to do for enlisted PRs
}
console.log(`Performing experimental branch updating and merging for pull requests ${prnums.join(", ")}`);
@ -51,9 +51,8 @@ async function main() {
issue_number: num,
body: `This PR is configured as an experiment, and currently has rebase conflicts with master - please rebase onto master and fix the conflicts.`
});
throw new Error(`Rebase conflict detected in PR ${num} with master`);
}
return; // A PR is currently in conflict, give up
throw new Error(`Rebase conflict detected in PR ${num} with master`); // A PR is currently in conflict, give up
}
runSequence([
["git", ["fetch", "origin", `pull/${num}/head:${num}`]],

View file

@ -10099,9 +10099,9 @@ namespace ts {
return false;
}
function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, fullIndexType: Type, suppressNoImplicitAnyError: boolean, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags) {
function getPropertyNameFromIndex(indexType: Type, accessNode: StringLiteral | Identifier | ObjectBindingPattern | ArrayBindingPattern | ComputedPropertyName | NumericLiteral | IndexedAccessTypeNode | ElementAccessExpression | SyntheticExpression | undefined) {
const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined;
const propName = isTypeUsableAsPropertyName(indexType) ?
return isTypeUsableAsPropertyName(indexType) ?
getPropertyNameFromType(indexType) :
accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ?
getPropertyNameForKnownSymbolName(idText((<PropertyAccessExpression>accessExpression.argumentExpression).name)) :
@ -10109,6 +10109,11 @@ namespace ts {
// late bound names are handled in the first branch, so here we only need to handle normal names
getPropertyNameForPropertyNameNode(accessNode) :
undefined;
}
function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, fullIndexType: Type, suppressNoImplicitAnyError: boolean, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags) {
const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined;
const propName = getPropertyNameFromIndex(indexType, accessNode);
if (propName !== undefined) {
const prop = getPropertyOfType(objectType, propName);
if (prop) {
@ -13314,7 +13319,14 @@ namespace ts {
}
}
else if (isReadonlyArrayType(target) ? isArrayType(source) || isTupleType(source) : isArrayType(target) && isTupleType(source) && !source.target.readonly) {
return isRelatedTo(getIndexTypeOfType(source, IndexKind.Number) || anyType, getIndexTypeOfType(target, IndexKind.Number) || anyType, reportErrors);
if (relation !== identityRelation) {
return isRelatedTo(getIndexTypeOfType(source, IndexKind.Number) || anyType, getIndexTypeOfType(target, IndexKind.Number) || anyType, reportErrors);
}
else {
// By flags alone, we know that the `target` is a readonly array while the source is a normal array or tuple
// or `target` is an array and source is a tuple - in both cases the types cannot be identical, by construction
return Ternary.False;
}
}
// Consider a fresh empty object literal type "closed" under the subtype relationship - this way `{} <- {[idx: string]: any} <- fresh({})`
// and not `{} <- fresh({}) <- {[idx: string]: any}`
@ -20018,6 +20030,7 @@ namespace ts {
}
function checkJsxExpression(node: JsxExpression, checkMode?: CheckMode) {
checkGrammarJsxExpression(node);
if (node.expression) {
const type = checkExpression(node.expression, checkMode);
if (node.dotDotDotToken && type !== anyType && !isArrayType(type)) {
@ -22494,7 +22507,10 @@ namespace ts {
case SyntaxKind.ElementAccessExpression:
const expr = (<PropertyAccessExpression | ElementAccessExpression>node).expression;
if (isIdentifier(expr)) {
const symbol = getSymbolAtLocation(expr);
let symbol = getSymbolAtLocation(expr);
if (symbol && symbol.flags & SymbolFlags.Alias) {
symbol = resolveAlias(symbol);
}
return !!(symbol && (symbol.flags & SymbolFlags.Enum) && getEnumKind(symbol) === EnumKind.Literal);
}
}
@ -25321,7 +25337,7 @@ namespace ts {
forEach(node.types, checkSourceElement);
}
function checkIndexedAccessIndexType(type: Type, accessNode: Node) {
function checkIndexedAccessIndexType(type: Type, accessNode: IndexedAccessTypeNode | ElementAccessExpression) {
if (!(type.flags & TypeFlags.IndexedAccess)) {
return type;
}
@ -25337,9 +25353,20 @@ namespace ts {
}
// Check if we're indexing with a numeric type and if either object or index types
// is a generic type with a constraint that has a numeric index signature.
if (getIndexInfoOfType(getApparentType(objectType), IndexKind.Number) && isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) {
const apparentObjectType = getApparentType(objectType);
if (getIndexInfoOfType(apparentObjectType, IndexKind.Number) && isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) {
return type;
}
if (isGenericObjectType(objectType)) {
const propertyName = getPropertyNameFromIndex(indexType, accessNode);
if (propertyName) {
const propertySymbol = forEachType(apparentObjectType, t => getPropertyOfType(t, propertyName));
if (propertySymbol && getDeclarationModifierFlagsFromSymbol(propertySymbol) & ModifierFlags.NonPublicAccessibilityModifier) {
error(accessNode, Diagnostics.Private_or_protected_member_0_cannot_be_accessed_on_a_type_parameter, unescapeLeadingUnderscores(propertyName));
return errorType;
}
}
}
error(accessNode, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType));
return errorType;
}
@ -31889,6 +31916,12 @@ namespace ts {
}
}
function checkGrammarJsxExpression(node: JsxExpression) {
if (node.expression && isCommaSequence(node.expression)) {
return grammarErrorOnNode(node.expression, Diagnostics.JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array);
}
}
function checkGrammarForInOrForOfStatement(forInOrOfStatement: ForInOrOfStatement): boolean {
if (checkGrammarStatementInAmbientContext(forInOrOfStatement)) {
return true;

View file

@ -2963,6 +2963,10 @@
"category": "Error",
"code": 4104
},
"Private or protected member '{0}' cannot be accessed on a type parameter.": {
"category": "Error",
"code": 4105
},
"The current host does not support the '{0}' option.": {
"category": "Error",
@ -5005,5 +5009,9 @@
"Classes may not have a field named 'constructor'.": {
"category": "Error",
"code": 18006
},
"JSX expressions may not use the comma operator. Did you mean to write an array?": {
"category": "Error",
"code": 18007
}
}

View file

@ -4430,14 +4430,18 @@ namespace ts {
if (token() !== SyntaxKind.CloseBraceToken) {
node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken);
node.expression = parseAssignmentExpressionOrHigher();
// Only an AssignmentExpression is valid here per the JSX spec,
// but we can unambiguously parse a comma sequence and provide
// a better error message in grammar checking.
node.expression = parseExpression();
}
if (inExpressionContext) {
parseExpected(SyntaxKind.CloseBraceToken);
}
else {
parseExpected(SyntaxKind.CloseBraceToken, /*message*/ undefined, /*shouldAdvance*/ false);
scanJsxText();
if (parseExpected(SyntaxKind.CloseBraceToken, /*message*/ undefined, /*shouldAdvance*/ false)) {
scanJsxText();
}
}
return finishNode(node);

View file

@ -583,6 +583,21 @@ namespace FourSlash {
});
}
public verifyErrorExistsAtRange(range: Range, code: number, expectedMessage?: string) {
const span = ts.createTextSpanFromRange(range);
const hasMatchingError = ts.some(
this.getDiagnostics(range.fileName),
({ code, messageText, start, length }) =>
code === code &&
(!expectedMessage || expectedMessage === messageText) &&
ts.isNumber(start) && ts.isNumber(length) &&
ts.textSpansEqual(span, { start, length }));
if (!hasMatchingError) {
this.raiseError(`No error with code ${code} found at provided range.`);
}
}
public verifyNumberOfErrorsInCurrentFile(expected: number) {
const errors = this.getDiagnostics(this.activeFile.fileName);
const actual = errors.length;
@ -4009,6 +4024,10 @@ namespace FourSlashInterface {
this.state.verifyNoErrors();
}
public errorExistsAtRange(range: FourSlash.Range, code: number, message?: string) {
this.state.verifyErrorExistsAtRange(range, code, message);
}
public numberOfErrorsInCurrentFile(expected: number) {
this.state.verifyNumberOfErrorsInCurrentFile(expected);
}

View file

@ -0,0 +1,33 @@
# How does TypeScript formatting work?
To format code you need to have a formatting context and a `SourceFile`. The formatting context contains
all user settings like tab size, newline character, etc.
The end result of formatting is represented by TextChange objects which hold the new string content, and
the text to replace it with.
```ts
export interface TextChange {
span: TextSpan; // start, length
newText: string;
}
```
## Internals
Most of the exposed APIs internally are `format*` and they all set up and configure `formatSpan` which could be considered the root call for formatting. Span in this case refers to the range of
the sourcefile which should be formatted.
The formatSpan then uses a scanner (either with or without JSX support) which starts at the highest
node the covers the span of text and recurses down through the node's children.
As it recurses, `processNode` is called on the children setting the indentation is decided and passed
through into each of that node's children.
The meat of formatting decisions is made via `processPair`, the pair here being the current node and the previous node. `processPair` which mutates the formatting context to represent the current place in the scanner and requests a set of rules which can be applied to the items via `createRulesMap`.
There are a lot of rules, which you can find in [rules.ts](./rules.ts) each one has a left and right reference to nodes or token ranges and note of what action should be applied by the formatter.
### Where is this used?
The formatter is used mainly from any language service operation that inserts or modifies code. The formatter is not exported publicly, and so all usage can only come through the language server.

View file

@ -229,6 +229,7 @@ namespace ts.formatting {
rule("NoSpaceBeforeNonNullAssertionOperator", anyToken, SyntaxKind.ExclamationToken, [isNonJsxSameLineTokenContext, isNonNullAssertionContext], RuleAction.Delete),
rule("NoSpaceAfterNewKeywordOnConstructorSignature", SyntaxKind.NewKeyword, SyntaxKind.OpenParenToken, [isNonJsxSameLineTokenContext, isConstructorSignatureContext], RuleAction.Delete),
rule("SpaceLessThanAndNonJSXTypeAnnotation", SyntaxKind.LessThanToken, SyntaxKind.LessThanToken, [isNonJsxSameLineTokenContext], RuleAction.Space),
];
// These rules are applied after high priority
@ -349,6 +350,18 @@ namespace ts.formatting {
];
}
/**
* A rule takes a two tokens (left/right) and a particular context
* for which you're meant to look at them. You then declare what should the
* whitespace annotation be between these tokens via the action param.
*
* @param debugName Name to print
* @param left The left side of the comparison
* @param right The right side of the comparison
* @param context A set of filters to narrow down the space in which this formatter rule applies
* @param action a declaration of the expected whitespace
* @param flags whether the rule deletes a line or not, defaults to no-op
*/
function rule(
debugName: string,
left: SyntaxKind | ReadonlyArray<SyntaxKind> | TokenRange,

View file

@ -143,6 +143,7 @@ class CompilerTest {
this.tsConfigFiles = [];
if (testCaseContent.tsConfig) {
assert.equal(testCaseContent.tsConfig.fileNames.length, 0, `list of files in tsconfig is not currently supported`);
assert.equal(testCaseContent.tsConfig.raw.exclude, undefined, `exclude in tsconfig is not currently supported`);
tsConfigOptions = ts.cloneCompilerOptions(testCaseContent.tsConfig.options);
this.tsConfigFiles.push(this.createHarnessTestFile(testCaseContent.tsConfigFileUnitData!, rootDir, ts.combinePaths(rootDir, tsConfigOptions.configFilePath)));

View file

@ -14,7 +14,7 @@ namespace Harness.Parallel.Host {
const isatty = tty.isatty(1) && tty.isatty(2);
const path = require("path") as typeof import("path");
const { fork } = require("child_process") as typeof import("child_process");
const { statSync } = require("fs") as typeof import("fs");
const { statSync, readFileSync } = require("fs") as typeof import("fs");
// NOTE: paths for module and types for FailedTestReporter _do not_ line up due to our use of --outFile for run.js
// tslint:disable-next-line:variable-name
@ -192,6 +192,31 @@ namespace Harness.Parallel.Host {
return `tsrunner-${runner}://${test}`;
}
function skipCostlyTests(tasks: Task[]) {
if (statSync("tests/.test-cost.json")) {
const costs = JSON.parse(readFileSync("tests/.test-cost.json", "utf8")) as {
totalTime: number,
totalEdits: number,
data: { name: string, time: number, edits: number, costs: number }[]
};
let skippedEdits = 0;
let skippedTime = 0;
const skippedTests = new Set<string>();
let i = 0;
for (; i < costs.data.length && (skippedEdits / costs.totalEdits) < (skipPercent / 100); i++) {
skippedEdits += costs.data[i].edits;
skippedTime += costs.data[i].time;
skippedTests.add(costs.data[i].name);
}
console.log(`Skipped ${i} expensive tests; estimated time savings of ${(skippedTime / costs.totalTime * 100).toFixed(2)}% with --skipPercent=${skipPercent.toFixed(2)} chance of missing a test.`);
return tasks.filter(t => !skippedTests.has(t.file));
}
else {
console.log("No cost analysis discovered.");
return tasks;
}
}
function startDelayed(perfData: { [testHash: string]: number } | undefined, totalCost: number) {
console.log(`Discovered ${tasks.length} unittest suites` + (newTasks.length ? ` and ${newTasks.length} new suites.` : "."));
console.log("Discovering runner-based tests...");
@ -231,6 +256,7 @@ namespace Harness.Parallel.Host {
}
tasks.sort((a, b) => a.size - b.size);
tasks = tasks.concat(newTasks);
tasks = skipCostlyTests(tasks);
const batchCount = workerCount;
const packfraction = 0.9;
const chunkSize = 1000; // ~1KB or 1s for sending batches near the end of a test

View file

@ -65,6 +65,7 @@ let runUnitTests: boolean | undefined;
let stackTraceLimit: number | "full" | undefined;
let noColors = false;
let keepFailed = false;
let skipPercent = 5;
interface TestConfig {
light?: boolean;
@ -78,6 +79,7 @@ interface TestConfig {
noColors?: boolean;
timeout?: number;
keepFailed?: boolean;
skipPercent?: number;
}
interface TaskSet {
@ -109,6 +111,9 @@ function handleTestConfig() {
if (testConfig.keepFailed) {
keepFailed = true;
}
if (testConfig.skipPercent !== undefined) {
skipPercent = testConfig.skipPercent;
}
if (testConfig.stackTraceLimit === "full") {
(<any>Error).stackTraceLimit = Infinity;

1
tests/.test-cost.json Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,33 @@
//// [tests/cases/conformance/expressions/typeAssertions/constAssertionOnEnum.ts] ////
//// [enum.ts]
export enum Foo {
A,
B,
}
//// [test.ts]
import {Foo} from './enum';
enum Bar {
A,
B,
}
let foo = Foo.A as const;
let bar = Bar.A as const;
//// [enum.js]
export var Foo;
(function (Foo) {
Foo[Foo["A"] = 0] = "A";
Foo[Foo["B"] = 1] = "B";
})(Foo || (Foo = {}));
//// [test.js]
import { Foo } from './enum';
var Bar;
(function (Bar) {
Bar[Bar["A"] = 0] = "A";
Bar[Bar["B"] = 1] = "B";
})(Bar || (Bar = {}));
let foo = Foo.A;
let bar = Bar.A;

View file

@ -0,0 +1,36 @@
=== tests/cases/conformance/expressions/typeAssertions/enum.ts ===
export enum Foo {
>Foo : Symbol(Foo, Decl(enum.ts, 0, 0))
A,
>A : Symbol(Foo.A, Decl(enum.ts, 0, 17))
B,
>B : Symbol(Foo.B, Decl(enum.ts, 1, 6))
}
=== tests/cases/conformance/expressions/typeAssertions/test.ts ===
import {Foo} from './enum';
>Foo : Symbol(Foo, Decl(test.ts, 0, 8))
enum Bar {
>Bar : Symbol(Bar, Decl(test.ts, 0, 27))
A,
>A : Symbol(Bar.A, Decl(test.ts, 2, 10))
B,
>B : Symbol(Bar.B, Decl(test.ts, 3, 6))
}
let foo = Foo.A as const;
>foo : Symbol(foo, Decl(test.ts, 6, 3))
>Foo.A : Symbol(Foo.A, Decl(enum.ts, 0, 17))
>Foo : Symbol(Foo, Decl(test.ts, 0, 8))
>A : Symbol(Foo.A, Decl(enum.ts, 0, 17))
let bar = Bar.A as const;
>bar : Symbol(bar, Decl(test.ts, 7, 3))
>Bar.A : Symbol(Bar.A, Decl(test.ts, 2, 10))
>Bar : Symbol(Bar, Decl(test.ts, 0, 27))
>A : Symbol(Bar.A, Decl(test.ts, 2, 10))

View file

@ -0,0 +1,38 @@
=== tests/cases/conformance/expressions/typeAssertions/enum.ts ===
export enum Foo {
>Foo : Foo
A,
>A : Foo.A
B,
>B : Foo.B
}
=== tests/cases/conformance/expressions/typeAssertions/test.ts ===
import {Foo} from './enum';
>Foo : typeof Foo
enum Bar {
>Bar : Bar
A,
>A : Bar.A
B,
>B : Bar.B
}
let foo = Foo.A as const;
>foo : Foo.A
>Foo.A as const : Foo.A
>Foo.A : Foo.A
>Foo : typeof Foo
>A : Foo.A
let bar = Bar.A as const;
>bar : Bar.A
>Bar.A as const : Bar.A
>Bar.A : Bar.A
>Bar : typeof Bar
>A : Bar.A

View file

@ -9,12 +9,8 @@ Starting "rush rebuild"
Executing a maximum of 1 simultaneous processes...
[@azure/abort-controller] started
XX of XX: [@azure/abort-controller] completed successfully in ? seconds
[@azure/cosmos] started
XX of XX: [@azure/cosmos] completed successfully in ? seconds
[@azure/event-hubs] started
XX of XX: [@azure/event-hubs] completed successfully in ? seconds
[@azure/service-bus] started
Warning: You have changed the public API signature for this project. Updating review/service-bus.api.md
[@azure/storage-blob] started
@ -27,6 +23,8 @@ XX of XX: [@azure/storage-file] completed successfully in ? seconds
XX of XX: [@azure/storage-queue] completed successfully in ? seconds
[@azure/template] started
XX of XX: [@azure/template] completed successfully in ? seconds
[@azure/abort-controller] started
XX of XX: [@azure/abort-controller] completed successfully in ? seconds
[@azure/core-http] started
XX of XX: [@azure/core-http] completed successfully in ? seconds
[@azure/core-paging] started
@ -37,21 +35,20 @@ XX of XX: [@azure/event-processor-host] completed successfully in ? seconds
XX of XX: [testhub] completed successfully in ? seconds
[@azure/identity] started
XX of XX: [@azure/identity] completed successfully in ? seconds
[@azure/core-amqp] started
[@azure/keyvault-certificates] started
XX of XX: [@azure/keyvault-certificates] completed successfully in ? seconds
[@azure/keyvault-keys] started
XX of XX: [@azure/keyvault-keys] completed successfully in ? seconds
[@azure/keyvault-secrets] started
XX of XX: [@azure/keyvault-secrets] completed successfully in ? seconds
[@azure/core-amqp] started
SUCCESS (16)
SUCCESS (15)
================================
@azure/abort-controller (? seconds)
@azure/core-http (? seconds)
@azure/core-paging (? seconds)
@azure/cosmos (? seconds)
@azure/event-hubs (? seconds)
@azure/event-processor-host (? seconds)
@azure/identity (? seconds)
@azure/keyvault-certificates (? seconds)
@ -71,14 +68,19 @@ SUCCESS WITH WARNINGS (1)
Warning: You have changed the public API signature for this project. Updating review/service-bus.api.md
================================
BLOCKED (1)
================================
@azure/event-hubs
================================
FAILURE (1)
================================
@azure/core-amqp (? seconds)
>>> @azure/core-amqp
tsc -p . && rollup -c 2>&1
src/errors.ts(579,20): error TS7053: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'typeof ConditionErrorNameMapper'.
src/errors.ts(600,34): error TS7053: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'typeof SystemErrorConditionMapper'.
src/errors.ts(601,20): error TS7053: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'typeof ConditionErrorNameMapper'.
src/errors.ts(586,20): error TS7053: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'typeof ConditionErrorNameMapper'.
src/errors.ts(607,34): error TS7053: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'typeof SystemErrorConditionMapper'.
src/errors.ts(608,20): error TS7053: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'typeof ConditionErrorNameMapper'.
================================
@ -92,4 +94,5 @@ Your version of Node.js (12.4.0) has not been tested with this release of Rush.
XX of XX: [@azure/service-bus] completed with warnings in ? seconds
XX of XX: [@azure/core-amqp] failed to build!
XX of XX: [@azure/event-hubs] blocked by [@azure/core-amqp]!
[@azure/core-amqp] Returned error code: 2

View file

@ -307,7 +307,7 @@ ts-jest[versions] (WARN) Version X.X.X-insiders.xxxxxxxx of typescript installed
ts-jest[versions] (WARN) Version X.X.X-insiders.xxxxxxxx of typescript installed has not been tested with ts-jest. If you're experiencing issues, consider using a supported version (>=2.7.0 <4.0.0). Please do not report issues in ts-jest if you are using unsupported versions.
================================
BLOCKED (26)
BLOCKED (27)
================================
@uifabric/api-docs
@uifabric/azure-themes
@ -320,6 +320,7 @@ BLOCKED (26)
@uifabric/fluent-theme
@uifabric/foundation-scenarios
@uifabric/lists
@uifabric/mdl2-theme
@uifabric/pr-deploy-site
@uifabric/react-cards
@uifabric/theme-samples
@ -411,6 +412,7 @@ XX of XX: [@uifabric/foundation-scenarios] blocked by [@uifabric/foundation]!
XX of XX: [@uifabric/lists] blocked by [@uifabric/foundation]!
XX of XX: [@uifabric/fluent-theme] blocked by [@uifabric/foundation]!
XX of XX: [@uifabric/tsx-editor] blocked by [@uifabric/foundation]!
XX of XX: [@uifabric/mdl2-theme] blocked by [@uifabric/foundation]!
XX of XX: [@uifabric/theme-samples] blocked by [@uifabric/foundation]!
XX of XX: [@uifabric/variants] blocked by [@uifabric/foundation]!
XX of XX: [server-rendered-app] blocked by [@uifabric/foundation]!

View file

@ -0,0 +1,27 @@
tests/cases/compiler/indexedAccessPrivateMemberOfGenericConstraint.ts(9,24): error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
tests/cases/compiler/indexedAccessPrivateMemberOfGenericConstraint.ts(9,32): error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
tests/cases/compiler/indexedAccessPrivateMemberOfGenericConstraint.ts(10,27): error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
tests/cases/compiler/indexedAccessPrivateMemberOfGenericConstraint.ts(11,27): error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
==== tests/cases/compiler/indexedAccessPrivateMemberOfGenericConstraint.ts (4 errors) ====
class A {
private a: number;
}
class B {
private a: string;
}
type X<T extends A> = [T["a"], (T | B)["a"]];
~~~~~~
!!! error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
~~~~~~~~~~~~
!!! error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
type Y<T extends A | B> = T["a"];
~~~~~~
!!! error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.
type Z<T extends A & B> = T["a"];
~~~~~~
!!! error TS4105: Private or protected member 'a' cannot be accessed on a type parameter.

View file

@ -0,0 +1,25 @@
//// [indexedAccessPrivateMemberOfGenericConstraint.ts]
class A {
private a: number;
}
class B {
private a: string;
}
type X<T extends A> = [T["a"], (T | B)["a"]];
type Y<T extends A | B> = T["a"];
type Z<T extends A & B> = T["a"];
//// [indexedAccessPrivateMemberOfGenericConstraint.js]
var A = /** @class */ (function () {
function A() {
}
return A;
}());
var B = /** @class */ (function () {
function B() {
}
return B;
}());

View file

@ -0,0 +1,37 @@
=== tests/cases/compiler/indexedAccessPrivateMemberOfGenericConstraint.ts ===
class A {
>A : Symbol(A, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 0, 0))
private a: number;
>a : Symbol(A.a, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 0, 9))
}
class B {
>B : Symbol(B, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 2, 1))
private a: string;
>a : Symbol(B.a, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 4, 9))
}
type X<T extends A> = [T["a"], (T | B)["a"]];
>X : Symbol(X, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 6, 1))
>T : Symbol(T, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 8, 7))
>A : Symbol(A, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 0, 0))
>T : Symbol(T, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 8, 7))
>T : Symbol(T, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 8, 7))
>B : Symbol(B, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 2, 1))
type Y<T extends A | B> = T["a"];
>Y : Symbol(Y, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 8, 45))
>T : Symbol(T, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 9, 7))
>A : Symbol(A, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 0, 0))
>B : Symbol(B, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 2, 1))
>T : Symbol(T, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 9, 7))
type Z<T extends A & B> = T["a"];
>Z : Symbol(Z, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 9, 33))
>T : Symbol(T, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 10, 7))
>A : Symbol(A, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 0, 0))
>B : Symbol(B, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 2, 1))
>T : Symbol(T, Decl(indexedAccessPrivateMemberOfGenericConstraint.ts, 10, 7))

View file

@ -0,0 +1,24 @@
=== tests/cases/compiler/indexedAccessPrivateMemberOfGenericConstraint.ts ===
class A {
>A : A
private a: number;
>a : number
}
class B {
>B : B
private a: string;
>a : string
}
type X<T extends A> = [T["a"], (T | B)["a"]];
>X : [T["a"], (B | T)["a"]]
type Y<T extends A | B> = T["a"];
>Y : T["a"]
type Z<T extends A & B> = T["a"];
>Z : T["a"]

View file

@ -28,18 +28,21 @@ var foo = /** @class */ (function () {
return foo;
}());
var x;
x = <any> {test} <any></any> };
x = <any> {test}: <any></any> };
x = <any><any></any>;
x = <foo>hello {<foo>} </foo>}
x = <foo>hello {<foo>} </foo>};
x = <foo test={<foo>}>hello</foo>}/>
x = <foo test={<foo>}>hello{<foo>}</foo>}
x = <foo test={<foo>}>hello{<foo>}</foo>};
x = <foo>x</foo>, x = <foo />;
<foo>{<foo><foo>{/foo/.test(x) ? <foo><foo></foo> : <foo><foo></foo>}</foo>}</foo>
:
}</></>}</></>}/></></></>;
}
</></>}</></>}/></></></>;

View file

@ -123,7 +123,7 @@ var x = <div>one</div>, <div>two</div>;
var x = <div>one</div> /* intervening comment */, /* intervening comment */ <div>two</div>;
;
//// [20.jsx]
<a>{"str"}}</a>;
<a>{"str"};}</a>;
//// [21.jsx]
<span className="a" id="b"/>;
//// [22.jsx]

View file

@ -1,9 +1,8 @@
tests/cases/conformance/jsx/file.tsx(11,36): error TS1005: '}' expected.
tests/cases/conformance/jsx/file.tsx(11,44): error TS1003: Identifier expected.
tests/cases/conformance/jsx/file.tsx(11,46): error TS1161: Unterminated regular expression literal.
tests/cases/conformance/jsx/file.tsx(11,30): error TS2695: Left side of comma operator is unused and has no side effects.
tests/cases/conformance/jsx/file.tsx(11,30): error TS18007: JSX expressions may not use the comma operator. Did you mean to write an array?
==== tests/cases/conformance/jsx/file.tsx (3 errors) ====
==== tests/cases/conformance/jsx/file.tsx (2 errors) ====
declare module JSX {
interface Element { }
interface IntrinsicElements {
@ -15,10 +14,8 @@ tests/cases/conformance/jsx/file.tsx(11,46): error TS1161: Unterminated regular
const class1 = "foo";
const class2 = "bar";
const elem = <div className={class1, class2}/>;
~
!!! error TS1005: '}' expected.
~
!!! error TS1003: Identifier expected.
!!! error TS1161: Unterminated regular expression literal.
~~~~~~
!!! error TS2695: Left side of comma operator is unused and has no side effects.
~~~~~~~~~~~~~~
!!! error TS18007: JSX expressions may not use the comma operator. Did you mean to write an array?

View file

@ -16,5 +16,4 @@ const elem = <div className={class1, class2}/>;
// This should be a parse error
var class1 = "foo";
var class2 = "bar";
var elem = <div className={class1} class2/>;
/>;;
var elem = <div className={class1, class2}/>;

View file

@ -25,5 +25,5 @@ const elem = <div className={class1, class2}/>;
>div : Symbol(JSX.IntrinsicElements, Decl(file.tsx, 1, 22))
>className : Symbol(className, Decl(file.tsx, 10, 17))
>class1 : Symbol(class1, Decl(file.tsx, 8, 5))
>class2 : Symbol(class2, Decl(file.tsx, 10, 36))
>class2 : Symbol(class2, Decl(file.tsx, 9, 5))

View file

@ -18,10 +18,10 @@ const class2 = "bar";
const elem = <div className={class1, class2}/>;
>elem : JSX.Element
><div className={class1, class2 : JSX.Element
><div className={class1, class2}/> : JSX.Element
>div : any
>className : string
>class1, class2 : "bar"
>class1 : "foo"
>class2 : true
>/>; : RegExp
>class2 : "bar"

View file

@ -8,8 +8,7 @@
"module": "commonjs",
"moduleResolution": "node",
"outDir": "bin"
},
"exclude": [ "node_modules" ]
}
}
==== /index.ts (1 errors) ====
/// <reference path="/typings/index.d.ts" />

View file

@ -1,26 +1,14 @@
tests/cases/conformance/jsx/file.tsx(4,11): error TS17008: JSX element 'div' has no corresponding closing tag.
tests/cases/conformance/jsx/file.tsx(4,19): error TS1109: Expression expected.
tests/cases/conformance/jsx/file.tsx(7,11): error TS2304: Cannot find name 'a'.
tests/cases/conformance/jsx/file.tsx(7,12): error TS1005: '}' expected.
tests/cases/conformance/jsx/file.tsx(8,1): error TS1005: '</' expected.
==== tests/cases/conformance/jsx/file.tsx (5 errors) ====
==== tests/cases/conformance/jsx/file.tsx (1 errors) ====
declare namespace JSX { interface Element { } }
function foo() {
var x = <div> { </div>
~~~
!!! error TS17008: JSX element 'div' has no corresponding closing tag.
~~
!!! error TS1109: Expression expected.
}
// Shouldn't see any errors down here
var y = { a: 1 };
~
!!! error TS2304: Cannot find name 'a'.
~
!!! error TS1005: '}' expected.
!!! error TS1005: '</' expected.

View file

@ -10,9 +10,7 @@ var y = { a: 1 };
//// [file.jsx]
function foo() {
var x = <div> {}div>
}
// Shouldn't see any errors down here
var y = {a} 1 };
</>;
var x = <div> {} </div>;
}
// Shouldn't see any errors down here
var y = { a: 1 };

View file

@ -11,4 +11,6 @@ function foo() {
}
// Shouldn't see any errors down here
var y = { a: 1 };
>y : Symbol(y, Decl(file.tsx, 6, 3))
>a : Symbol(a, Decl(file.tsx, 6, 9))

View file

@ -6,13 +6,15 @@ function foo() {
var x = <div> { </div>
>x : JSX.Element
><div> { </div>}// Shouldn't see any errors down herevar y = { a: 1 }; : JSX.Element
><div> { </div> : JSX.Element
>div : any
> : any
>div : any
}
// Shouldn't see any errors down here
var y = { a: 1 };
>a : any
> : any
>y : { a: number; }
>{ a: 1 } : { a: number; }
>a : number
>1 : 1

View file

@ -25,7 +25,7 @@ node_modules/adonis-framework/src/Encryption/index.js(85,23): error TS8024: JSDo
node_modules/adonis-framework/src/Encryption/index.js(87,15): error TS2304: Cannot find name 'Mixed'.
node_modules/adonis-framework/src/Encryption/index.js(101,62): error TS2345: Argument of type 'string' is not assignable to parameter of type 'Utf8AsciiBinaryEncoding'.
node_modules/adonis-framework/src/Encryption/index.js(114,15): error TS2304: Cannot find name 'Mixed'.
node_modules/adonis-framework/src/Encryption/index.js(119,18): error TS2554: Expected 2 arguments, but got 1.
node_modules/adonis-framework/src/Encryption/index.js(119,23): error TS2554: Expected 2 arguments, but got 1.
node_modules/adonis-framework/src/Encryption/index.js(183,15): error TS2304: Cannot find name 'Mixed'.
node_modules/adonis-framework/src/Encryption/index.js(197,15): error TS2304: Cannot find name 'Mixed'.
node_modules/adonis-framework/src/Encryption/index.js(209,14): error TS8024: JSDoc '@param' tag has name 'object', but there is no parameter with that name.
@ -69,7 +69,7 @@ node_modules/adonis-framework/src/File/index.js(273,5): error TS2322: Type 'bool
Type '""' is not assignable to type 'boolean'.
node_modules/adonis-framework/src/Helpers/index.js(105,3): error TS2322: Type 'null' is not assignable to type 'string'.
node_modules/adonis-framework/src/Helpers/index.js(106,3): error TS2322: Type 'null' is not assignable to type 'string'.
node_modules/adonis-framework/src/Helpers/index.js(164,10): error TS2554: Expected 3 arguments, but got 2.
node_modules/adonis-framework/src/Helpers/index.js(164,18): error TS2554: Expected 3 arguments, but got 2.
node_modules/adonis-framework/src/Helpers/index.js(178,45): error TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
Type 'undefined' is not assignable to type 'string'.
node_modules/adonis-framework/src/Helpers/index.js(224,45): error TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
@ -100,8 +100,8 @@ node_modules/adonis-framework/src/Request/index.js(482,15): error TS2304: Cannot
node_modules/adonis-framework/src/Request/index.js(499,17): error TS2551: Property '_params' does not exist on type 'Request'. Did you mean 'param'?
node_modules/adonis-framework/src/Request/index.js(523,15): error TS2304: Cannot find name 'Objecr'.
node_modules/adonis-framework/src/Request/index.js(572,23): error TS8029: JSDoc '@param' tag has name 'pattern', but there is no parameter with that name. It would match 'arguments' if it had an array type.
node_modules/adonis-framework/src/Request/index.js(600,12): error TS2554: Expected 2 arguments, but got 1.
node_modules/adonis-framework/src/Request/index.js(600,35): error TS2554: Expected 2 arguments, but got 1.
node_modules/adonis-framework/src/Request/index.js(600,17): error TS2554: Expected 2 arguments, but got 1.
node_modules/adonis-framework/src/Request/index.js(600,40): error TS2554: Expected 2 arguments, but got 1.
node_modules/adonis-framework/src/Request/index.js(663,23): error TS8024: JSDoc '@param' tag has name 'encodings', but there is no parameter with that name.
node_modules/adonis-framework/src/Response/index.js(44,7): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
node_modules/adonis-framework/src/Response/index.js(56,7): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
@ -157,7 +157,7 @@ node_modules/adonis-framework/src/Route/resource.js(296,15): error TS2304: Canno
node_modules/adonis-framework/src/Route/resource.js(314,62): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type 'any[]'.
node_modules/adonis-framework/src/Server/helpers.js(17,29): error TS8024: JSDoc '@param' tag has name 'appNamespace', but there is no parameter with that name.
node_modules/adonis-framework/src/Server/index.js(17,21): error TS2307: Cannot find module 'adonis-fold'.
node_modules/adonis-framework/src/Server/index.js(54,21): error TS2554: Expected 4 arguments, but got 3.
node_modules/adonis-framework/src/Server/index.js(54,29): error TS2554: Expected 4 arguments, but got 3.
node_modules/adonis-framework/src/Server/index.js(137,25): error TS8024: JSDoc '@param' tag has name 'handlers', but there is no parameter with that name.
node_modules/adonis-framework/src/Server/index.js(252,15): error TS2304: Cannot find name 'instance'.
node_modules/adonis-framework/src/Server/index.js(252,24): error TS1005: '}' expected.
@ -211,7 +211,7 @@ node_modules/adonis-framework/src/View/Form/index.js(147,63): error TS2345: Argu
node_modules/adonis-framework/src/View/Form/index.js(151,58): error TS2345: Argument of type 'string | any[]' is not assignable to parameter of type 'any[]'.
Type 'string' is not assignable to type 'any[]'.
node_modules/adonis-framework/src/View/Form/index.js(415,37): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string'.
node_modules/adonis-framework/src/View/Form/index.js(578,20): error TS2554: Expected 2 arguments, but got 1.
node_modules/adonis-framework/src/View/Form/index.js(578,25): error TS2554: Expected 2 arguments, but got 1.
node_modules/adonis-framework/src/View/Form/index.js(601,51): error TS2345: Argument of type 'number | any[]' is not assignable to parameter of type 'string | any[]'.
Type 'number' is not assignable to type 'string | any[]'.
node_modules/adonis-framework/src/View/index.js(50,23): error TS8024: JSDoc '@param' tag has name 'template_path', but there is no parameter with that name.

View file

@ -19,7 +19,7 @@ lib/adapters/xhr.js(81,51): error TS2345: Argument of type 'null' is not assigna
lib/adapters/xhr.js(84,7): error TS2322: Type 'null' is not assignable to type 'XMLHttpRequest'.
lib/adapters/xhr.js(93,7): error TS2322: Type 'null' is not assignable to type 'XMLHttpRequest'.
lib/adapters/xhr.js(163,9): error TS2322: Type 'null' is not assignable to type 'XMLHttpRequest'.
lib/axios.js(23,3): error TS2554: Expected 3 arguments, but got 2.
lib/axios.js(23,9): error TS2554: Expected 3 arguments, but got 2.
lib/axios.js(25,3): error TS2739: Type '(...args: any[]) => any' is missing the following properties from type 'Axios': defaults, interceptors, request, getUri
lib/axios.js(32,7): error TS2339: Property 'Axios' does not exist on type 'Axios'.
lib/axios.js(35,7): error TS2339: Property 'create' does not exist on type 'Axios'.

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,6 @@
// @filename: /foo/tsconfig.json
{
"compilerOptions": { "composite": true },
"exclude": [ "node_modules" ]
"compilerOptions": { "composite": true }
}
// @filename: /foo/node_modules/myModule/index.ts

View file

@ -0,0 +1,11 @@
class A {
private a: number;
}
class B {
private a: string;
}
type X<T extends A> = [T["a"], (T | B)["a"]];
type Y<T extends A | B> = T["a"];
type Z<T extends A & B> = T["a"];

View file

@ -11,8 +11,7 @@
"module": "commonjs",
"moduleResolution": "node",
"outDir": "bin"
},
"exclude": [ "node_modules" ]
}
}
// @filename: /node_modules/shortid/node_modules/z/index.js
// z will not be found because maxNodeModulesJsDepth: 0

View file

@ -0,0 +1,18 @@
// @strict: true
// @target: esnext
// @filename: enum.ts
export enum Foo {
A,
B,
}
// @filename: test.ts
import {Foo} from './enum';
enum Bar {
A,
B,
}
let foo = Foo.A as const;
let bar = Bar.A as const;

View file

@ -0,0 +1,8 @@
///<reference path="fourslash.ts"/>
// https://github.com/microsoft/TypeScript/issues/14589
/////*1*/if (<number>foo < <number>bar) {}
format.document();
goTo.marker("1")
verify.currentLineContentIs(`if (<number>foo < <number>bar) { }`)

View file

@ -42,6 +42,8 @@
//
// TODO: figure out a better solution to the API exposure problem.
/// <reference path="../../../src/compiler/diagnosticInformationMap.generated.ts" />
declare module ts {
export type MapKey = string | number;
export interface Map<T> {
@ -70,6 +72,21 @@ declare module ts {
text: string;
}
enum DiagnosticCategory {
Warning,
Error,
Suggestion,
Message
}
interface DiagnosticMessage {
key: string;
category: DiagnosticCategory;
code: number;
message: string;
reportsUnnecessary?: {};
}
function flatMap<T, U>(array: ReadonlyArray<T>, mapfn: (x: T, i: number) => U | ReadonlyArray<U> | undefined): U[];
}
@ -238,6 +255,7 @@ declare namespace FourSlashInterface {
signatureHelp(...options: VerifySignatureHelpOptions[], ): void;
// Checks that there are no compile errors.
noErrors(): void;
errorExistsAtRange(range: Range, code: number, message?: string): void;
numberOfErrorsInCurrentFile(expected: number): void;
baselineCurrentFileBreakpointLocations(): void;
baselineCurrentFileNameOrDottedNameSpans(): void;

View file

@ -0,0 +1,12 @@
/// <reference path="fourslash.ts" />
//@Filename: jsxExpressionFollowedByIdentifier.tsx
////declare var React: any;
////const a = <div>{<div />[|x|]}</div>
////const b = <div x={<div />[|x|]} />
test.ranges().forEach(range => {
verify.errorExistsAtRange(range, ts.Diagnostics._0_expected.code, "'}' expected.");
// This is just to ensure getting quick info doesnt crash
verify.not.quickInfoExists();
});

View file

@ -0,0 +1,11 @@
/// <reference path="fourslash.ts" />
//@Filename: jsxExpressionWithCommaExpression.tsx
//@jsx: react
////declare var React: any;
////declare var x: string;
////const a = <div x={[|x, x|]} />
////const b = <div>{[|x, x|]}</div>
verify.getSyntacticDiagnostics([]);
test.ranges().forEach(range => verify.errorExistsAtRange(range, 18006));

View file

@ -0,0 +1,15 @@
/// <reference path="fourslash.ts" />
////type TypeEq<A, B> = (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? true : false;
////
////const /*2*/test1: TypeEq<number[], [number, ...number[]]> = false;
////
////declare const foo: [number, ...number[]];
////declare const bar: number[];
////
////const /*1*/test2: TypeEq<typeof foo, typeof bar> = false;
goTo.marker("1");
verify.quickInfoIs("const test2: false");
goTo.marker("2");
verify.quickInfoIs("const test1: false");