Merge branch 'master' into builderApi

This commit is contained in:
Sheetal Nandi
2018-01-19 15:56:40 -08:00
199 changed files with 17079 additions and 6234 deletions
+2 -1
View File
@@ -18,4 +18,5 @@ Jakefile.js
.settings/
.travis.yml
.vscode/
test.config
test.config
package-lock.json
+30 -4
View File
@@ -1,10 +1,34 @@
<!-- BUGS: Please use this template. -->
<!-- QUESTIONS: This is not a general support forum! Ask Qs at http://stackoverflow.com/questions/tagged/typescript -->
<!-- SUGGESTIONS: See https://github.com/Microsoft/TypeScript-wiki/blob/master/Writing-Good-Design-Proposals.md -->
<!-- 🚨 STOP 🚨 𝗦𝗧𝗢𝗣 🚨 𝑺𝑻𝑶𝑷 🚨 -->
<!--
Half of all issues filed here are duplicates, answered in the FAQ, or not appropriate for the bug tracker.
Please help us by doing the following steps before logging an issue:
* Search: https://github.com/Microsoft/TypeScript/search?type=Issues
* Read the CONTRIBUTING guidelines: https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md
* Read the FAQ: https://github.com/Microsoft/TypeScript/wiki/FAQ
-->
<!-- If you have a QUESTION:
THIS IS NOT A FORUM FOR QUESTIONS.
Ask questions at http://stackoverflow.com/questions/tagged/typescript
or https://gitter.im/Microsoft/TypeScript
-->
<!-- If you have a SUGGESTION:
Most suggestion reports are duplicates, please search extra hard before logging a new suggestion.
See https://github.com/Microsoft/TypeScript-wiki/blob/master/Writing-Good-Design-Proposals.md
-->
<!-- If you have a BUG:
Please fill in the *entire* template below.
-->
<!-- Please try to reproduce the issue with `typescript@next`. It may have already been fixed. -->
**TypeScript Version:** 2.7.0-dev.201xxxxx
<!-- Search terms you tried before logging this (so others can find this issue more easily) -->
**Search Terms:**
**Code**
```ts
@@ -16,4 +40,6 @@
**Actual behavior:**
**Related:**
**Playground Link:** <!-- A link to a TypeScript Playground "Share" link which demonstrates this behavior -->
**Related Issues:**
+27 -11
View File
@@ -6564,7 +6564,7 @@ namespace ts {
// b) It references `arguments` somewhere
const lastParam = lastOrUndefined(declaration.parameters);
const lastParamTags = lastParam && getJSDocParameterTags(lastParam);
const lastParamVariadicType = lastParamTags && firstDefined(lastParamTags, p =>
const lastParamVariadicType = firstDefined(lastParamTags, p =>
p.typeExpression && isJSDocVariadicType(p.typeExpression.type) ? p.typeExpression.type : undefined);
if (!lastParamVariadicType && !containsArgumentsReference(declaration)) {
return false;
@@ -9639,7 +9639,7 @@ namespace ts {
}
else if (target.flags & TypeFlags.IndexedAccess) {
// A type S is related to a type T[K] if S is related to A[K], where K is string-like and
// A is the apparent type of T.
// A is the constraint of T.
const constraint = getConstraintOfIndexedAccess(<IndexedAccessType>target);
if (constraint) {
if (result = isRelatedTo(source, constraint, reportErrors)) {
@@ -9675,7 +9675,7 @@ namespace ts {
}
else if (source.flags & TypeFlags.IndexedAccess) {
// A type S[K] is related to a type T if A[K] is related to T, where K is string-like and
// A is the apparent type of S.
// A is the constraint of S.
const constraint = getConstraintOfIndexedAccess(<IndexedAccessType>source);
if (constraint) {
if (result = isRelatedTo(constraint, target, reportErrors)) {
@@ -9683,10 +9683,11 @@ namespace ts {
return result;
}
}
else if (target.flags & TypeFlags.IndexedAccess && (<IndexedAccessType>source).indexType === (<IndexedAccessType>target).indexType) {
// if we have indexed access types with identical index types, see if relationship holds for
// the two object types.
else if (target.flags & TypeFlags.IndexedAccess) {
if (result = isRelatedTo((<IndexedAccessType>source).objectType, (<IndexedAccessType>target).objectType, reportErrors)) {
result &= isRelatedTo((<IndexedAccessType>source).indexType, (<IndexedAccessType>target).indexType, reportErrors);
}
if (result) {
errorInfo = saveErrorInfo;
return result;
}
@@ -10967,7 +10968,7 @@ namespace ts {
return type === typeParameter || type.flags & TypeFlags.UnionOrIntersection && forEach((<UnionOrIntersectionType>type).types, t => isTypeParameterAtTopLevel(t, typeParameter));
}
/** Create an object with properties named in the string literal type. Every property has type `{}` */
/** Create an object with properties named in the string literal type. Every property has type `any` */
function createEmptyObjectTypeFromStringLiteral(type: Type) {
const members = createSymbolTable();
forEachType(type, t => {
@@ -10976,7 +10977,7 @@ namespace ts {
}
const name = escapeLeadingUnderscores((t as StringLiteralType).value);
const literalProp = createSymbol(SymbolFlags.Property, name);
literalProp.type = emptyObjectType;
literalProp.type = anyType;
if (t.symbol) {
literalProp.declarations = t.symbol.declarations;
literalProp.valueDeclaration = t.symbol.valueDeclaration;
@@ -11031,7 +11032,9 @@ namespace ts {
const templateType = getTemplateTypeFromMappedType(target);
const inference = createInferenceInfo(typeParameter);
inferTypes([inference], sourceType, templateType);
return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) : emptyObjectType;
return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) :
inference.contraCandidates ? getCommonSubtype(inference.contraCandidates) :
emptyObjectType;
}
function getUnmatchedProperty(source: Type, target: Type, requireOptionalProperties: boolean) {
@@ -18377,6 +18380,9 @@ namespace ts {
function checkObjectLiteralAssignment(node: ObjectLiteralExpression, sourceType: Type): Type {
const properties = node.properties;
if (strictNullChecks && properties.length === 0) {
return checkNonNullType(sourceType, node);
}
for (const p of properties) {
checkObjectLiteralDestructuringPropertyAssignment(sourceType, p, properties);
}
@@ -21446,7 +21452,13 @@ namespace ts {
if (isBindingPattern(node.name)) {
// Don't validate for-in initializer as it is already an error
if (node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement) {
checkTypeAssignableTo(checkExpressionCached(node.initializer), getWidenedTypeForVariableLikeDeclaration(node), node, /*headMessage*/ undefined);
const initializerType = checkExpressionCached(node.initializer);
if (strictNullChecks && node.name.elements.length === 0) {
checkNonNullType(initializerType, node);
}
else {
checkTypeAssignableTo(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, /*headMessage*/ undefined);
}
checkParameterInitializer(node);
}
return;
@@ -26196,7 +26208,7 @@ namespace ts {
function checkGrammarBindingElement(node: BindingElement) {
if (node.dotDotDotToken) {
const elements = (<BindingPattern>node.parent).elements;
if (node !== lastOrUndefined(elements)) {
if (node !== last(elements)) {
return grammarErrorOnNode(node, Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
}
@@ -26204,6 +26216,10 @@ namespace ts {
return grammarErrorOnNode(node.name, Diagnostics.A_rest_element_cannot_contain_a_binding_pattern);
}
if (node.propertyName) {
return grammarErrorOnNode(node.name, Diagnostics.A_rest_element_cannot_have_a_property_name);
}
if (node.initializer) {
// Error on equals token which immediately precedes the initializer
return grammarErrorAtPos(node, node.initializer.pos - 1, 1, Diagnostics.A_rest_element_cannot_have_an_initializer);
+4
View File
@@ -183,6 +183,10 @@ namespace ts {
/** Like `forEach`, but suitable for use with numbers and strings (which may be falsy). */
export function firstDefined<T, U>(array: ReadonlyArray<T> | undefined, callback: (element: T, index: number) => U | undefined): U | undefined {
if (array === undefined) {
return undefined;
}
for (let i = 0; i < array.length; i++) {
const result = callback(array[i], i);
if (result !== undefined) {
+4 -4
View File
@@ -1976,6 +1976,10 @@
"category": "Error",
"code": 2565
},
"A rest element cannot have a property name.": {
"category": "Error",
"code": 2566
},
"JSX element attributes type '{0}' may not be a union type.": {
"category": "Error",
"code": 2600
@@ -3893,10 +3897,6 @@
"category": "Message",
"code": 95002
},
"Extract symbol": {
"category": "Message",
"code": 95003
},
"Extract to {0} in {1}": {
"category": "Message",
"code": 95004
+1 -1
View File
@@ -1268,12 +1268,12 @@ namespace ts {
}
function emitBindingElement(node: BindingElement) {
emitIfPresent(node.dotDotDotToken);
if (node.propertyName) {
emit(node.propertyName);
writePunctuation(":");
writeSpace();
}
emitIfPresent(node.dotDotDotToken);
emit(node.name);
emitInitializer(node.initializer);
}
+13 -4
View File
@@ -126,8 +126,8 @@ namespace ts {
case SyntaxKind.BindingElement:
return visitNodes(cbNode, cbNodes, node.decorators) ||
visitNodes(cbNode, cbNodes, node.modifiers) ||
visitNode(cbNode, (<BindingElement>node).propertyName) ||
visitNode(cbNode, (<BindingElement>node).dotDotDotToken) ||
visitNode(cbNode, (<BindingElement>node).propertyName) ||
visitNode(cbNode, (<BindingElement>node).name) ||
visitNode(cbNode, (<BindingElement>node).initializer);
case SyntaxKind.FunctionType:
@@ -6830,7 +6830,7 @@ namespace ts {
}
function parseTemplateTag(atToken: AtToken, tagName: Identifier): JSDocTemplateTag | undefined {
if (forEach(tags, t => t.kind === SyntaxKind.JSDocTemplateTag)) {
if (some(tags, isJSDocTemplateTag)) {
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.escapedText);
}
@@ -6839,14 +6839,14 @@ namespace ts {
const typeParametersPos = getNodePos();
while (true) {
const name = parseJSDocIdentifierName();
const typeParameter = <TypeParameterDeclaration>createNode(SyntaxKind.TypeParameter);
const name = parseJSDocIdentifierNameWithOptionalBraces();
skipWhitespace();
if (!name) {
parseErrorAtPosition(scanner.getStartPos(), 0, Diagnostics.Identifier_expected);
return undefined;
}
const typeParameter = <TypeParameterDeclaration>createNode(SyntaxKind.TypeParameter, name.pos);
typeParameter.name = name;
finishNode(typeParameter);
@@ -6869,6 +6869,15 @@ namespace ts {
return result;
}
function parseJSDocIdentifierNameWithOptionalBraces(): Identifier | undefined {
const parsedBrace = parseOptional(SyntaxKind.OpenBraceToken);
const res = parseJSDocIdentifierName();
if (parsedBrace) {
parseExpected(SyntaxKind.CloseBraceToken);
}
return res;
}
function nextJSDocToken(): JsDocSyntaxKind {
return currentToken = scanner.scanJSDocToken();
}
+4 -5
View File
@@ -474,11 +474,6 @@ namespace ts {
cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
}
// Ignore emits from the program
if (isEmittedFileOfProgram(resolutionHost.getCurrentProgram(), fileOrDirectory)) {
return;
}
// If the files are added to project root or node_modules directory, always run through the invalidation process
// Otherwise run through invalidation only if adding to the immediate directory
if (!allFilesHaveInvalidatedResolution &&
@@ -582,6 +577,10 @@ namespace ts {
if (!isPathWithDefaultFailedLookupExtension(fileOrDirectoryPath) && !customFailedLookupPaths.has(fileOrDirectoryPath)) {
return false;
}
// Ignore emits from the program
if (isEmittedFileOfProgram(resolutionHost.getCurrentProgram(), fileOrDirectoryPath)) {
return false;
}
// Resolution need to be invalidated if failed lookup location is same as the file or directory getting created
isChangedFailedLookupLocation = location => resolutionHost.toPath(location) === fileOrDirectoryPath;
}
+7 -1
View File
@@ -2029,7 +2029,13 @@ namespace ts {
return token !== undefined && isNonContextualKeyword(token);
}
export function isTrivia(token: SyntaxKind) {
export type TriviaKind = SyntaxKind.SingleLineCommentTrivia
| SyntaxKind.MultiLineCommentTrivia
| SyntaxKind.NewLineTrivia
| SyntaxKind.WhitespaceTrivia
| SyntaxKind.ShebangTrivia
| SyntaxKind.ConflictMarkerTrivia;
export function isTrivia(token: SyntaxKind): token is TriviaKind {
return SyntaxKind.FirstTriviaToken <= token && token <= SyntaxKind.LastTriviaToken;
}
+10 -7
View File
@@ -33,12 +33,15 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
});
}
private runTest(directoryName: string) {
describe(directoryName, () => {
// tslint:disable-next-line:no-this-assignment
const cls = this;
const timeout = 600_000; // 10 minutes
describe(directoryName, function(this: Mocha.ISuiteCallbackContext) {
this.timeout(timeout);
const cp = require("child_process");
it("should build successfully", () => {
let cwd = path.join(__dirname, "../../", this.testDir, directoryName);
const timeout = 600000; // 600s = 10 minutes
let cwd = path.join(__dirname, "../../", cls.testDir, directoryName);
const stdio = isWorker ? "pipe" : "inherit";
let types: string[];
if (fs.existsSync(path.join(cwd, "test.json"))) {
@@ -61,9 +64,9 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
fs.unlinkSync(path.join(cwd, "package-lock.json"));
}
if (fs.existsSync(path.join(cwd, "node_modules"))) {
require("del").sync(path.join(cwd, "node_modules"));
require("del").sync(path.join(cwd, "node_modules"), { force: true });
}
const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio });
const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout: timeout / 2, shell: true, stdio }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure
if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed: ${install.stderr.toString()}`);
}
const args = [path.join(__dirname, "tsc.js")];
@@ -71,8 +74,8 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
args.push("--types", types.join(","));
}
args.push("--noEmit");
Harness.Baseline.runBaseline(`${this.kind()}/${directoryName}.log`, () => {
return this.report(cp.spawnSync(`node`, args, { cwd, timeout, shell: true }), cwd);
Harness.Baseline.runBaseline(`${cls.kind()}/${directoryName}.log`, () => {
return cls.report(cp.spawnSync(`node`, args, { cwd, timeout, shell: true }), cwd);
});
});
});
+29 -14
View File
@@ -1102,20 +1102,30 @@ namespace FourSlash {
}
public verifyReferenceGroups(startRanges: Range | Range[], parts: FourSlashInterface.ReferenceGroup[]): void {
const fullExpected = ts.map(parts, ({ definition, ranges }) => ({ definition, ranges: ranges.map(rangeToReferenceEntry) }));
interface ReferenceGroupJson {
definition: string | { text: string, range: ts.TextSpan };
references: ts.ReferenceEntry[];
}
const fullExpected = ts.map<FourSlashInterface.ReferenceGroup, ReferenceGroupJson>(parts, ({ definition, ranges }) => ({
definition: typeof definition === "string" ? definition : { ...definition, range: textSpanFromRange(definition.range) },
references: ranges.map(rangeToReferenceEntry),
}));
for (const startRange of toArray(startRanges)) {
this.goToRangeStart(startRange);
const fullActual = ts.map(this.findReferencesAtCaret(), ({ definition, references }) => ({
definition: definition.displayParts.map(d => d.text).join(""),
ranges: references
}));
const fullActual = ts.map<ts.ReferencedSymbol, ReferenceGroupJson>(this.findReferencesAtCaret(), ({ definition, references }, i) => {
const text = definition.displayParts.map(d => d.text).join("");
return {
definition: typeof fullExpected[i].definition === "string" ? text : { text, range: definition.textSpan },
references,
};
});
this.assertObjectsEqual(fullActual, fullExpected);
}
function rangeToReferenceEntry(r: Range): ts.ReferenceEntry {
const { isWriteAccess, isDefinition, isInString } = (r.marker && r.marker.data) || { isWriteAccess: false, isDefinition: false, isInString: undefined };
const result: ts.ReferenceEntry = { fileName: r.fileName, textSpan: { start: r.start, length: r.end - r.start }, isWriteAccess: !!isWriteAccess, isDefinition: !!isDefinition };
const result: ts.ReferenceEntry = { fileName: r.fileName, textSpan: textSpanFromRange(r), isWriteAccess: !!isWriteAccess, isDefinition: !!isDefinition };
if (isInString !== undefined) {
result.isInString = isInString;
}
@@ -1139,7 +1149,7 @@ namespace FourSlash {
}
}
public verifySingleReferenceGroup(definition: string, ranges?: Range[]) {
public verifySingleReferenceGroup(definition: FourSlashInterface.ReferenceGroupDefinition, ranges?: Range[]) {
ranges = ranges || this.getRanges();
this.verifyReferenceGroups(ranges, [{ definition, ranges }]);
}
@@ -1305,8 +1315,13 @@ Actual: ${stringify(fullActual)}`);
}
public verifyRangesAreRenameLocations(options?: Range[] | { findInStrings?: boolean, findInComments?: boolean, ranges?: Range[] }) {
const ranges = ts.isArray(options) ? options : options && options.ranges || this.getRanges();
this.verifyRenameLocations(ranges, { ranges, ...options });
if (ts.isArray(options)) {
this.verifyRenameLocations(options, options);
}
else {
const ranges = options && options.ranges || this.getRanges();
this.verifyRenameLocations(ranges, { ranges, ...options });
}
}
public verifyRenameLocations(startRanges: Range | Range[], options: Range[] | { findInStrings?: boolean, findInComments?: boolean, ranges: Range[] }) {
@@ -2568,9 +2583,7 @@ Actual: ${stringify(fullActual)}`);
const originalContent = scriptInfo.content;
for (const codeFix of codeFixes) {
this.applyEdits(codeFix.changes[0].fileName, codeFix.changes[0].textChanges, /*isFormattingEdit*/ false);
let text = this.rangeText(ranges[0]);
// TODO:GH#18445 (remove this line to see errors in many `importNameCodeFix` tests)
text = text.replace(/\r\n/g, "\n");
const text = this.rangeText(ranges[0]);
actualTextArray.push(text);
scriptInfo.updateContent(originalContent);
}
@@ -4077,7 +4090,7 @@ namespace FourSlashInterface {
this.state.verifyNoReferences(markerNameOrRange);
}
public singleReferenceGroup(definition: string, ranges?: FourSlash.Range[]) {
public singleReferenceGroup(definition: ReferenceGroupDefinition, ranges?: FourSlash.Range[]) {
this.state.verifySingleReferenceGroup(definition, ranges);
}
@@ -4589,10 +4602,12 @@ namespace FourSlashInterface {
}
export interface ReferenceGroup {
definition: string;
definition: ReferenceGroupDefinition;
ranges: FourSlash.Range[];
}
export type ReferenceGroupDefinition = string | { text: string, range: FourSlash.Range };
export interface ApplyRefactorOptions {
refactorName: string;
actionName: string;
@@ -121,7 +121,6 @@ namespace ts {
const sourceFile = program.getSourceFile(path);
const context: RefactorContext = {
cancellationToken: { throwIfCancellationRequested: noop, isCancellationRequested: returnFalse },
newLineCharacter,
program,
file: sourceFile,
startPosition: selectionRange.start,
@@ -185,7 +184,6 @@ namespace ts {
const sourceFile = program.getSourceFile(f.path);
const context: RefactorContext = {
cancellationToken: { throwIfCancellationRequested: noop, isCancellationRequested: returnFalse },
newLineCharacter,
program,
file: sourceFile,
startPosition: selectionRange.start,
@@ -888,6 +888,9 @@
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add async modifier to containing function]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[将异步修饰符添加到包含函数]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -4620,6 +4623,9 @@
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[映射的对象类型隐式地含有 "any" 模板类型。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -888,6 +888,9 @@
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add async modifier to containing function]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[將 async 修飾詞新增至包含的函式]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -4620,6 +4623,9 @@
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[對應的物件類型隱含具有 'any' 範本類型。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -897,6 +897,9 @@
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add async modifier to containing function]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Přidat modifikátor async do obsahující funkce]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -4629,6 +4632,9 @@
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Typu mapovaného objektu má implicitně typ šablony any.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -885,6 +885,9 @@
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add async modifier to containing function]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Async-Modifizierer zur enthaltenden Funktion hinzufügen]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -4617,6 +4620,9 @@
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Der zugeordnete Objekttyp weist implizit einen any-Vorlagentyp auf.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -897,6 +897,9 @@
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add async modifier to containing function]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Agregar el modificador async a la función contenedora]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -4629,6 +4632,9 @@
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[El tipo de objeto asignado tiene implícitamente un tipo de plantilla "any".]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -897,6 +897,9 @@
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add async modifier to containing function]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Ajouter le modificateur async dans la fonction conteneur]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -4629,6 +4632,9 @@
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Le type d'objet mappé a implicitement un type de modèle 'any'.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -888,6 +888,9 @@
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add async modifier to containing function]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Aggiungere il modificatore async alla funzione contenitore]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -4620,6 +4623,9 @@
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Il tipo di oggetto con mapping contiene implicitamente un tipo di modello 'any'.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -888,6 +888,9 @@
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add async modifier to containing function]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[含まれている関数に async 修飾子を追加します]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -4620,6 +4623,9 @@
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[マップされたオブジェクト型のテンプレートの型は暗黙的に 'any' になります。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -888,6 +888,9 @@
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add async modifier to containing function]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[포함된 함수에 async 한정자 추가]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -4620,6 +4623,9 @@
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[매핑된 개체 형식에는 'any' 템플릿 형식이 암시적으로 포함됩니다.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -878,6 +878,9 @@
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add async modifier to containing function]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Dodaj modyfikator asynchroniczny do funkcji zawierającej]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -4610,6 +4613,9 @@
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Zmapowany typ obiektu niejawnie ma typ szablonu „any”.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -878,6 +878,9 @@
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add async modifier to containing function]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Adicione o modificador assíncrono que contém a função]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -4610,6 +4613,9 @@
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[O tipo de objeto mapeado implicitamente tem um tipo de modelo 'any'.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -887,6 +887,9 @@
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add async modifier to containing function]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Добавьте модификатор async в содержащую функцию]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -4619,6 +4622,9 @@
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Сопоставленный объект неявно имеет тип шаблона "любой".]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -881,6 +881,9 @@
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add async modifier to containing function]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[İçeren işleve zaman uyumsuz değiştirici ekle]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -4613,6 +4616,9 @@
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Eşleştirilmiş nesne türü örtük olarak 'any' şablon türüne sahip.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
+3 -3
View File
@@ -1810,9 +1810,9 @@ namespace ts.server {
let info = this.getScriptInfoForPath(path);
if (!info) {
const isDynamic = isDynamicFileName(fileName);
Debug.assert(isRootedDiskPath(fileName) || isDynamic || openedByClient, "Script info with non-dynamic relative file name can only be open script info");
Debug.assert(!isRootedDiskPath(fileName) || this.currentDirectory === currentDirectory || !this.openFilesWithNonRootedDiskPath.has(this.toCanonicalFileName(fileName)), "Open script files with non rooted disk path opened with current directory context cannot have same canonical names");
Debug.assert(!isDynamic || this.currentDirectory === currentDirectory, "Dynamic files must always have current directory context since containing external project name will always match the script info name.");
Debug.assert(isRootedDiskPath(fileName) || isDynamic || openedByClient, "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}\nScript info with non-dynamic relative file name can only be open script info`);
Debug.assert(!isRootedDiskPath(fileName) || this.currentDirectory === currentDirectory || !this.openFilesWithNonRootedDiskPath.has(this.toCanonicalFileName(fileName)), "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}\nOpen script files with non rooted disk path opened with current directory context cannot have same canonical names`);
Debug.assert(!isDynamic || this.currentDirectory === currentDirectory, "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}\nDynamic files must always have current directory context since containing external project name will always match the script info name.`);
// If the file is not opened by client and the file doesnot exist on the disk, return
if (!openedByClient && !isDynamic && !(hostToQueryFileExistsOn || this.host).fileExists(fileName)) {
return;
+2 -2
View File
@@ -1665,9 +1665,9 @@ namespace ts.server {
return { startPosition, endPosition };
}
private mapCodeAction(project: Project, { description, changes: unmappedChanges, commands }: CodeAction): protocol.CodeAction {
private mapCodeAction(project: Project, { description, changes: unmappedChanges, commands, fixId }: CodeFixAction): protocol.CodeFixAction {
const changes = unmappedChanges.map(change => this.mapTextChangesToCodeEditsUsingScriptinfo(change, project.getScriptInfoForNormalizedPath(toNormalizedPath(change.fileName))));
return { description, changes, commands };
return { description, changes, commands, fixId };
}
private mapTextChangesToCodeEdits(project: Project, textChanges: ReadonlyArray<FileTextChanges>): protocol.FileCodeEdits[] {
+38 -29
View File
@@ -619,37 +619,46 @@ namespace ts {
return start;
}
// Don't bother with newlines/whitespace.
if (kind === SyntaxKind.NewLineTrivia || kind === SyntaxKind.WhitespaceTrivia) {
continue;
}
// Only bother with the trivia if it at least intersects the span of interest.
if (isComment(kind)) {
classifyComment(token, kind, start, width);
// Classifying a comment might cause us to reuse the trivia scanner
// (because of jsdoc comments). So after we classify the comment make
// sure we set the scanner position back to where it needs to be.
triviaScanner.setTextPos(end);
continue;
}
if (kind === SyntaxKind.ConflictMarkerTrivia) {
const text = sourceFile.text;
const ch = text.charCodeAt(start);
// for the <<<<<<< and >>>>>>> markers, we just add them in as comments
// in the classification stream.
if (ch === CharacterCodes.lessThan || ch === CharacterCodes.greaterThan) {
pushClassification(start, width, ClassificationType.comment);
switch (kind) {
case SyntaxKind.NewLineTrivia:
case SyntaxKind.WhitespaceTrivia:
// Don't bother with newlines/whitespace.
continue;
}
// for the ||||||| and ======== markers, add a comment for the first line,
// and then lex all subsequent lines up until the end of the conflict marker.
Debug.assert(ch === CharacterCodes.bar || ch === CharacterCodes.equals);
classifyDisabledMergeCode(text, start, end);
case SyntaxKind.SingleLineCommentTrivia:
case SyntaxKind.MultiLineCommentTrivia:
// Only bother with the trivia if it at least intersects the span of interest.
classifyComment(token, kind, start, width);
// Classifying a comment might cause us to reuse the trivia scanner
// (because of jsdoc comments). So after we classify the comment make
// sure we set the scanner position back to where it needs to be.
triviaScanner.setTextPos(end);
continue;
case SyntaxKind.ConflictMarkerTrivia:
const text = sourceFile.text;
const ch = text.charCodeAt(start);
// for the <<<<<<< and >>>>>>> markers, we just add them in as comments
// in the classification stream.
if (ch === CharacterCodes.lessThan || ch === CharacterCodes.greaterThan) {
pushClassification(start, width, ClassificationType.comment);
continue;
}
// for the ||||||| and ======== markers, add a comment for the first line,
// and then lex all subsequent lines up until the end of the conflict marker.
Debug.assert(ch === CharacterCodes.bar || ch === CharacterCodes.equals);
classifyDisabledMergeCode(text, start, end);
break;
case SyntaxKind.ShebangTrivia:
// TODO: Maybe we should classify these.
break;
default:
Debug.assertNever(kind);
}
}
}
-1
View File
@@ -10,7 +10,6 @@ namespace ts {
export interface CodeFixContextBase extends textChanges.TextChangesContext {
sourceFile: SourceFile;
program: Program;
host: LanguageServiceHost;
cancellationToken: CancellationToken;
}
@@ -9,12 +9,14 @@ namespace ts.codefix {
registerCodeFix({
errorCodes,
getCodeActions(context) {
const { sourceFile, program, newLineCharacter, span } = context;
const { sourceFile, program, span } = context;
if (!isInJavaScriptFile(sourceFile) || !isCheckJsEnabledForFile(sourceFile, program.getCompilerOptions())) {
return undefined;
}
const newLineCharacter = getNewLineOrDefaultFromHost(context.host, context.formatContext.options);
return [{
description: getLocaleSpecificMessage(Diagnostics.Ignore_this_error_message),
changes: [createFileTextChanges(sourceFile.fileName, [getIgnoreCommentLocationForLocation(sourceFile, span.start, newLineCharacter)])],
@@ -36,7 +38,7 @@ namespace ts.codefix {
fixIds: [fixId], // No point applying as a group, doing it once will fix all errors
getAllCodeActions: context => codeFixAllWithTextChanges(context, errorCodes, (changes, err) => {
if (err.start !== undefined) {
changes.push(getIgnoreCommentLocationForLocation(err.file!, err.start, context.newLineCharacter));
changes.push(getIgnoreCommentLocationForLocation(err.file!, err.start, getNewLineOrDefaultFromHost(context.host, context.formatContext.options)));
}
}),
});
@@ -142,7 +142,7 @@ namespace ts.codefix {
return typeNode || createKeywordTypeNode(SyntaxKind.AnyKeyword);
}
function createAddPropertyDeclarationAction(context: textChanges.TextChangesContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, makeStatic: boolean, tokenName: string, typeNode: TypeNode): CodeFixAction {
function createAddPropertyDeclarationAction(context: CodeFixContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, makeStatic: boolean, tokenName: string, typeNode: TypeNode): CodeFixAction {
const description = formatStringFromArgs(getLocaleSpecificMessage(makeStatic ? Diagnostics.Declare_static_property_0 : Diagnostics.Declare_property_0), [tokenName]);
const changes = textChanges.ChangeTracker.with(context, t => addPropertyDeclaration(t, classDeclarationSourceFile, classDeclaration, tokenName, typeNode, makeStatic));
return { description, changes, fixId };
@@ -159,7 +159,7 @@ namespace ts.codefix {
changeTracker.insertNodeAtClassStart(classDeclarationSourceFile, classDeclaration, property);
}
function createAddIndexSignatureAction(context: textChanges.TextChangesContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, tokenName: string, typeNode: TypeNode): CodeFixAction {
function createAddIndexSignatureAction(context: CodeFixContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, tokenName: string, typeNode: TypeNode): CodeFixAction {
// Index signatures cannot have the static modifier.
const stringTypeNode = createKeywordTypeNode(SyntaxKind.StringKeyword);
const indexingParameter = createParameter(
@@ -181,7 +181,7 @@ namespace ts.codefix {
return { description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_index_signature_for_property_0), [tokenName]), changes, fixId: undefined };
}
function getActionForMethodDeclaration(context: textChanges.TextChangesContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, token: Identifier, callExpression: CallExpression, makeStatic: boolean, inJs: boolean): CodeFixAction | undefined {
function getActionForMethodDeclaration(context: CodeFixContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, token: Identifier, callExpression: CallExpression, makeStatic: boolean, inJs: boolean): CodeFixAction | undefined {
const description = formatStringFromArgs(getLocaleSpecificMessage(makeStatic ? Diagnostics.Declare_static_method_0 : Diagnostics.Declare_method_0), [token.text]);
const changes = textChanges.ChangeTracker.with(context, t => addMethodDeclaration(t, classDeclarationSourceFile, classDeclaration, token, callExpression, makeStatic, inJs));
return { description, changes, fixId };
+2 -7
View File
@@ -29,12 +29,8 @@ namespace ts.codefix {
symbolName: string;
}
interface SymbolAndTokenContext extends SymbolContext {
interface ImportCodeFixContext extends SymbolContext {
symbolToken: Identifier | undefined;
}
interface ImportCodeFixContext extends SymbolAndTokenContext {
host: LanguageServiceHost;
program: Program;
checker: TypeChecker;
compilerOptions: CompilerOptions;
@@ -173,7 +169,6 @@ namespace ts.codefix {
const symbolToken = cast(getTokenAtPosition(context.sourceFile, context.span.start, /*includeJsDocComment*/ false), isIdentifier);
return {
host: context.host,
newLineCharacter: context.newLineCharacter,
formatContext: context.formatContext,
sourceFile: context.sourceFile,
program,
@@ -472,7 +467,7 @@ namespace ts.codefix {
addJsExtension: boolean,
): string | undefined {
const roots = getEffectiveTypeRoots(options, host);
return roots && firstDefined(roots, unNormalizedTypeRoot => {
return firstDefined(roots, unNormalizedTypeRoot => {
const typeRoot = toPath(unNormalizedTypeRoot, /*basePath*/ undefined, getCanonicalFileName);
if (startsWith(moduleFileName, typeRoot)) {
return removeExtensionAndIndexPostFix(moduleFileName.substring(typeRoot.length + 1), options, addJsExtension);
-1
View File
@@ -627,7 +627,6 @@ namespace ts.Completions {
host,
program,
checker,
newLineCharacter: host.getNewLine(),
compilerOptions,
sourceFile,
formatContext,
+1 -1
View File
@@ -44,7 +44,7 @@ namespace ts.FindAllReferences {
export function findReferencedSymbols(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray<SourceFile>, sourceFile: SourceFile, position: number): ReferencedSymbol[] | undefined {
const referencedSymbols = findAllReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position);
const checker = program.getTypeChecker();
return !referencedSymbols || !referencedSymbols.length ? undefined : mapDefined(referencedSymbols, ({ definition, references }) =>
return !referencedSymbols || !referencedSymbols.length ? undefined : mapDefined<SymbolAndEntries, ReferencedSymbol>(referencedSymbols, ({ definition, references }) =>
// Only include referenced symbols that have a valid definition.
definition && { definition: definitionToReferencedSymbolDefinitionInfo(definition, checker), references: references.map(toReferenceEntry) });
}
+20 -25
View File
@@ -14,10 +14,14 @@ namespace ts.formatting {
kind: SyntaxKind;
}
export interface TextRangeWithTriviaKind extends TextRange {
kind: TriviaKind;
}
export interface TokenInfo {
leadingTrivia: TextRangeWithKind[];
leadingTrivia: TextRangeWithTriviaKind[];
token: TextRangeWithKind;
trailingTrivia: TextRangeWithKind[];
trailingTrivia: TextRangeWithTriviaKind[];
}
const enum Constants {
@@ -66,11 +70,6 @@ namespace ts.formatting {
recomputeIndentation(lineAddedByFormatting: boolean): void;
}
interface Indentation {
indentation: number;
delta: number;
}
export function formatOnEnter(position: number, sourceFile: SourceFile, formatContext: FormatContext): TextChange[] {
const line = sourceFile.getLineAndCharacterOfPosition(position).line;
if (line === 0) {
@@ -469,39 +468,35 @@ namespace ts.formatting {
inheritedIndentation: number,
parent: Node,
parentDynamicIndentation: DynamicIndentation,
effectiveParentStartLine: number): Indentation {
let indentation = inheritedIndentation;
let delta = SmartIndenter.shouldIndentChildNode(node) ? options.indentSize : 0;
effectiveParentStartLine: number
): { indentation: number, delta: number } {
const delta = SmartIndenter.shouldIndentChildNode(node) ? options.indentSize : 0;
if (effectiveParentStartLine === startLine) {
// if node is located on the same line with the parent
// - inherit indentation from the parent
// - push children if either parent of node itself has non-zero delta
indentation = startLine === lastIndentedLine
? indentationOnLastIndentedLine
: parentDynamicIndentation.getIndentation();
delta = Math.min(options.indentSize, parentDynamicIndentation.getDelta(node) + delta);
return {
indentation: startLine === lastIndentedLine ? indentationOnLastIndentedLine : parentDynamicIndentation.getIndentation(),
delta: Math.min(options.indentSize, parentDynamicIndentation.getDelta(node) + delta)
};
}
else if (indentation === Constants.Unknown) {
else if (inheritedIndentation === Constants.Unknown) {
if (node.kind === SyntaxKind.OpenParenToken && startLine === lastIndentedLine) {
// the is used for chaining methods formatting
// - we need to get the indentation on last line and the delta of parent
indentation = indentationOnLastIndentedLine;
delta = parentDynamicIndentation.getDelta(node);
return { indentation: indentationOnLastIndentedLine, delta: parentDynamicIndentation.getDelta(node) };
}
else if (SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile)) {
indentation = parentDynamicIndentation.getIndentation();
return { indentation: parentDynamicIndentation.getIndentation(), delta };
}
else {
indentation = parentDynamicIndentation.getIndentation() + parentDynamicIndentation.getDelta(node);
return { indentation: parentDynamicIndentation.getIndentation() + parentDynamicIndentation.getDelta(node), delta };
}
}
return {
indentation,
delta
};
else {
return { indentation: inheritedIndentation, delta };
}
}
function getFirstNonDecoratorTokenOfNode(node: Node) {
+4 -4
View File
@@ -31,8 +31,8 @@ namespace ts.formatting {
scanner.setTextPos(startPos);
let wasNewLine = true;
let leadingTrivia: TextRangeWithKind[] | undefined;
let trailingTrivia: TextRangeWithKind[] | undefined;
let leadingTrivia: TextRangeWithTriviaKind[] | undefined;
let trailingTrivia: TextRangeWithTriviaKind[] | undefined;
let savedPos: number;
let lastScanAction: ScanAction | undefined;
@@ -77,7 +77,7 @@ namespace ts.formatting {
// consume leading trivia
scanner.scan();
const item = {
const item: TextRangeWithTriviaKind = {
pos,
end: scanner.getStartPos(),
kind: t
@@ -188,7 +188,7 @@ namespace ts.formatting {
if (!isTrivia(currentToken)) {
break;
}
const trivia = {
const trivia: TextRangeWithTriviaKind = {
pos: scanner.getStartPos(),
end: scanner.getTextPos(),
kind: currentToken
+18 -66
View File
@@ -127,30 +127,16 @@ namespace ts.GoToDefinition {
}
const symbol = typeChecker.getSymbolAtLocation(node);
if (!symbol) {
return undefined;
}
const type = typeChecker.getTypeOfSymbolAtLocation(symbol, node);
const type = symbol && typeChecker.getTypeOfSymbolAtLocation(symbol, node);
if (!type) {
return undefined;
}
if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Enum)) {
const result: DefinitionInfo[] = [];
forEach((<UnionType>type).types, t => {
if (t.symbol) {
addRange(/*to*/ result, /*from*/ getDefinitionFromSymbol(typeChecker, t.symbol, node));
}
});
return result;
return flatMap((<UnionType>type).types, t => t.symbol && getDefinitionFromSymbol(typeChecker, t.symbol, node));
}
if (!type.symbol) {
return undefined;
}
return getDefinitionFromSymbol(typeChecker, type.symbol, node);
return type.symbol && getDefinitionFromSymbol(typeChecker, type.symbol, node);
}
export function getDefinitionAndBoundSpan(program: Program, sourceFile: SourceFile, position: number): DefinitionInfoAndBoundSpan {
@@ -199,66 +185,32 @@ namespace ts.GoToDefinition {
}
function getDefinitionFromSymbol(typeChecker: TypeChecker, symbol: Symbol, node: Node): DefinitionInfo[] {
const result: DefinitionInfo[] = [];
const declarations = symbol.getDeclarations();
const { symbolName, symbolKind, containerName } = getSymbolInfo(typeChecker, symbol, node);
return getConstructSignatureDefinition() || getCallSignatureDefinition() || map(symbol.declarations, declaration => createDefinitionInfo(declaration, symbolKind, symbolName, containerName));
if (!tryAddConstructSignature(symbol, node, symbolKind, symbolName, containerName, result) &&
!tryAddCallSignature(symbol, node, symbolKind, symbolName, containerName, result)) {
// Just add all the declarations.
forEach(declarations, declaration => {
result.push(createDefinitionInfo(declaration, symbolKind, symbolName, containerName));
});
}
return result;
function tryAddConstructSignature(symbol: Symbol, location: Node, symbolKind: ScriptElementKind, symbolName: string, containerName: string, result: DefinitionInfo[]) {
function getConstructSignatureDefinition(): DefinitionInfo[] | undefined {
// Applicable only if we are in a new expression, or we are on a constructor declaration
// and in either case the symbol has a construct signature definition, i.e. class
if (isNewExpressionTarget(location) || location.kind === SyntaxKind.ConstructorKeyword) {
if (symbol.flags & SymbolFlags.Class) {
// Find the first class-like declaration and try to get the construct signature.
for (const declaration of symbol.getDeclarations()) {
if (isClassLike(declaration)) {
return tryAddSignature(
declaration.members, /*selectConstructors*/ true, symbolKind, symbolName, containerName, result);
}
}
Debug.fail("Expected declaration to have at least one class-like declaration");
}
if (isNewExpressionTarget(node) || node.kind === SyntaxKind.ConstructorKeyword && symbol.flags & SymbolFlags.Class) {
const cls = find(symbol.declarations, isClassLike) || Debug.fail("Expected declaration to have at least one class-like declaration");
return getSignatureDefinition(cls.members, /*selectConstructors*/ true);
}
return false;
}
function tryAddCallSignature(symbol: Symbol, location: Node, symbolKind: ScriptElementKind, symbolName: string, containerName: string, result: DefinitionInfo[]) {
if (isCallExpressionTarget(location) || isNewExpressionTarget(location) || isNameOfFunctionDeclaration(location)) {
return tryAddSignature(symbol.declarations, /*selectConstructors*/ false, symbolKind, symbolName, containerName, result);
}
return false;
function getCallSignatureDefinition(): DefinitionInfo[] | undefined {
return isCallExpressionTarget(node) || isNewExpressionTarget(node) || isNameOfFunctionDeclaration(node)
? getSignatureDefinition(symbol.declarations, /*selectConstructors*/ false)
: undefined;
}
function tryAddSignature(signatureDeclarations: ReadonlyArray<Declaration> | undefined, selectConstructors: boolean, symbolKind: ScriptElementKind, symbolName: string, containerName: string, result: DefinitionInfo[]) {
function getSignatureDefinition(signatureDeclarations: ReadonlyArray<Declaration> | undefined, selectConstructors: boolean): DefinitionInfo[] | undefined {
if (!signatureDeclarations) {
return false;
return undefined;
}
const declarations: Declaration[] = [];
let definition: Declaration | undefined;
for (const d of signatureDeclarations) {
if (selectConstructors ? d.kind === SyntaxKind.Constructor : isSignatureDeclaration(d)) {
declarations.push(d);
if ((<FunctionLikeDeclaration>d).body) definition = d;
}
}
if (declarations.length) {
result.push(createDefinitionInfo(definition || lastOrUndefined(declarations), symbolKind, symbolName, containerName));
return true;
}
return false;
const declarations = signatureDeclarations.filter(selectConstructors ? isConstructorDeclaration : isSignatureDeclaration);
return declarations.length
? [createDefinitionInfo(find(declarations, d => !!(<FunctionLikeDeclaration>d).body) || last(declarations), symbolKind, symbolName, containerName)]
: undefined;
}
}
+3 -9
View File
@@ -1,12 +1,6 @@
/* @internal */
namespace ts {
export interface Refactor {
/** An unique code associated with each refactor */
name: string;
/** Description of the refactor to display in the UI of the editor */
description: string;
/** Compute the associated code actions */
getEditsForAction(context: RefactorContext, actionName: string): RefactorEditInfo | undefined;
@@ -19,7 +13,6 @@ namespace ts {
startPosition: number;
endPosition?: number;
program: Program;
host: LanguageServiceHost;
cancellationToken?: CancellationToken;
}
@@ -28,8 +21,9 @@ namespace ts {
// e.g. nonSuggestableRefactors[refactorCode] -> the refactor you want
const refactors: Map<Refactor> = createMap<Refactor>();
export function registerRefactor(refactor: Refactor) {
refactors.set(refactor.name, refactor);
/** @param name An unique code associated with each refactor. Does not have to be human-readable. */
export function registerRefactor(name: string, refactor: Refactor) {
refactors.set(name, refactor);
}
export function getApplicableRefactors(context: RefactorContext): ApplicableRefactorInfo[] {
@@ -1,13 +1,10 @@
/* @internal */
namespace ts.refactor.annotateWithTypeFromJSDoc {
const refactorName = "Annotate with type from JSDoc";
const actionName = "annotate";
const description = Diagnostics.Annotate_with_type_from_JSDoc.message;
registerRefactor(refactorName, { getEditsForAction, getAvailableActions });
const annotateTypeFromJSDoc: Refactor = {
name: "Annotate with type from JSDoc",
description: Diagnostics.Annotate_with_type_from_JSDoc.message,
getEditsForAction,
getAvailableActions
};
type DeclarationWithType =
| FunctionLikeDeclaration
| VariableDeclaration
@@ -15,8 +12,6 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
| PropertySignature
| PropertyDeclaration;
registerRefactor(annotateTypeFromJSDoc);
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
if (isInJavaScriptFile(context.file)) {
return undefined;
@@ -25,11 +20,11 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
const node = getTokenAtPosition(context.file, context.startPosition, /*includeJsDocComment*/ false);
if (hasUsableJSDoc(findAncestor(node, isDeclarationWithType))) {
return [{
name: annotateTypeFromJSDoc.name,
description: annotateTypeFromJSDoc.description,
name: refactorName,
description,
actions: [
{
description: annotateTypeFromJSDoc.description,
description,
name: actionName
}
]
@@ -1,16 +1,10 @@
/* @internal */
namespace ts.refactor.convertFunctionToES6Class {
const refactorName = "Convert to ES2015 class";
const actionName = "convert";
const convertFunctionToES6Class: Refactor = {
name: "Convert to ES2015 class",
description: Diagnostics.Convert_function_to_an_ES2015_class.message,
getEditsForAction,
getAvailableActions
};
registerRefactor(convertFunctionToES6Class);
const description = Diagnostics.Convert_function_to_an_ES2015_class.message;
registerRefactor(refactorName, { getEditsForAction, getAvailableActions });
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
if (!isInJavaScriptFile(context.file)) {
@@ -29,11 +23,11 @@ namespace ts.refactor.convertFunctionToES6Class {
if ((symbol.flags & SymbolFlags.Function) && symbol.members && (symbol.members.size > 0)) {
return [
{
name: convertFunctionToES6Class.name,
description: convertFunctionToES6Class.description,
name: refactorName,
description,
actions: [
{
description: convertFunctionToES6Class.description,
description,
name: actionName
}
]
+5 -12
View File
@@ -1,15 +1,8 @@
/* @internal */
namespace ts.refactor {
const actionName = "Convert to ES6 module";
const convertToEs6Module: Refactor = {
name: actionName,
description: getLocaleSpecificMessage(Diagnostics.Convert_to_ES6_module),
getEditsForAction,
getAvailableActions,
};
registerRefactor(convertToEs6Module);
const description = getLocaleSpecificMessage(Diagnostics.Convert_to_ES6_module);
registerRefactor(actionName, { getEditsForAction, getAvailableActions });
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
const { file, startPosition } = context;
@@ -20,11 +13,11 @@ namespace ts.refactor {
const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false);
return !isAtTriggerLocation(file, node) ? undefined : [
{
name: convertToEs6Module.name,
description: convertToEs6Module.description,
name: actionName,
description,
actions: [
{
description: convertToEs6Module.description,
description,
name: actionName,
},
],
+4 -10
View File
@@ -3,14 +3,8 @@
/* @internal */
namespace ts.refactor.extractSymbol {
const extractSymbol: Refactor = {
name: "Extract Symbol",
description: getLocaleSpecificMessage(Diagnostics.Extract_symbol),
getAvailableActions,
getEditsForAction,
};
registerRefactor(extractSymbol);
const refactorName = "Extract Symbol";
registerRefactor(refactorName, { getAvailableActions, getEditsForAction });
/**
* Compute the associated code actions
@@ -77,7 +71,7 @@ namespace ts.refactor.extractSymbol {
if (functionActions.length) {
infos.push({
name: extractSymbol.name,
name: refactorName,
description: getLocaleSpecificMessage(Diagnostics.Extract_function),
actions: functionActions
});
@@ -85,7 +79,7 @@ namespace ts.refactor.extractSymbol {
if (constantActions.length) {
infos.push({
name: extractSymbol.name,
name: refactorName,
description: getLocaleSpecificMessage(Diagnostics.Extract_constant),
actions: constantActions
});
@@ -1,15 +1,9 @@
/* @internal */
namespace ts.refactor.installTypesForPackage {
const refactorName = "Install missing types package";
const actionName = "install";
const installTypesForPackage: Refactor = {
name: "Install missing types package",
description: "Install missing types package",
getEditsForAction,
getAvailableActions,
};
registerRefactor(installTypesForPackage);
const description = "Install missing types package";
registerRefactor(refactorName, { getEditsForAction, getAvailableActions });
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
if (getStrictOptionValue(context.program.getCompilerOptions(), "noImplicitAny")) {
@@ -20,8 +14,8 @@ namespace ts.refactor.installTypesForPackage {
const action = getAction(context);
return action && [
{
name: installTypesForPackage.name,
description: installTypesForPackage.description,
name: refactorName,
description,
actions: [
{
description: action.description,
+5 -12
View File
@@ -1,15 +1,8 @@
/* @internal */
namespace ts.refactor.installTypesForPackage {
const actionName = "Convert to default import";
const useDefaultImport: Refactor = {
name: actionName,
description: getLocaleSpecificMessage(Diagnostics.Convert_to_default_import),
getEditsForAction,
getAvailableActions,
};
registerRefactor(useDefaultImport);
const description = getLocaleSpecificMessage(Diagnostics.Convert_to_default_import);
registerRefactor(actionName, { getEditsForAction, getAvailableActions });
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
const { file, startPosition, program } = context;
@@ -31,11 +24,11 @@ namespace ts.refactor.installTypesForPackage {
return [
{
name: useDefaultImport.name,
description: useDefaultImport.description,
name: actionName,
description,
actions: [
{
description: useDefaultImport.description,
description,
name: actionName,
},
],
+2 -5
View File
@@ -1887,12 +1887,11 @@ namespace ts {
synchronizeHostData();
const sourceFile = getValidSourceFile(fileName);
const span = createTextSpanFromBounds(start, end);
const newLineCharacter = getNewLineOrDefaultFromHost(host);
const formatContext = formatting.getFormatContext(formatOptions);
return flatMap(deduplicate(errorCodes, equateValues, compareValues), errorCode => {
cancellationToken.throwIfCancellationRequested();
return codefix.getFixes({ errorCode, sourceFile, span, program, newLineCharacter, host, cancellationToken, formatContext });
return codefix.getFixes({ errorCode, sourceFile, span, program, host, cancellationToken, formatContext });
});
}
@@ -1900,10 +1899,9 @@ namespace ts {
synchronizeHostData();
Debug.assert(scope.type === "file");
const sourceFile = getValidSourceFile(scope.fileName);
const newLineCharacter = getNewLineOrDefaultFromHost(host);
const formatContext = formatting.getFormatContext(formatOptions);
return codefix.getAllFixes({ fixId, sourceFile, program, newLineCharacter, host, cancellationToken, formatContext });
return codefix.getAllFixes({ fixId, sourceFile, program, host, cancellationToken, formatContext });
}
function applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
@@ -2134,7 +2132,6 @@ namespace ts {
startPosition,
endPosition,
program: getProgram(),
newLineCharacter: formatOptions ? formatOptions.newLineCharacter : host.getNewLine(),
host,
formatContext: formatting.getFormatContext(formatOptions),
cancellationToken,
+2 -2
View File
@@ -187,7 +187,7 @@ namespace ts.textChanges {
}
export interface TextChangesContext {
newLineCharacter: string;
host: LanguageServiceHost;
formatContext: ts.formatting.FormatContext;
}
@@ -199,7 +199,7 @@ namespace ts.textChanges {
private readonly nodesInsertedAtClassStarts = createMap<{ sourceFile: SourceFile, cls: ClassLikeDeclaration, members: ClassElement[] }>();
public static fromContext(context: TextChangesContext): ChangeTracker {
return new ChangeTracker(context.newLineCharacter === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed, context.formatContext);
return new ChangeTracker(getNewLineOrDefaultFromHost(context.host, context.formatContext.options) === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed, context.formatContext);
}
public static with(context: TextChangesContext, cb: (tracker: ChangeTracker) => void): FileTextChanges[] {
+4 -2
View File
@@ -1259,8 +1259,10 @@ namespace ts {
/**
* The default is CRLF.
*/
export function getNewLineOrDefaultFromHost(host: LanguageServiceHost | LanguageServiceShimHost) {
return host.getNewLine ? host.getNewLine() : carriageReturnLineFeed;
export function getNewLineOrDefaultFromHost(host: LanguageServiceHost | LanguageServiceShimHost, formatSettings?: FormatCodeSettings) {
return (formatSettings && formatSettings.newLineCharacter) ||
(host.getNewLine && host.getNewLine()) ||
carriageReturnLineFeed;
}
export function lineBreakPart() {
+1 -1
View File
@@ -7243,7 +7243,7 @@ declare namespace ts.server {
private getCombinedCodeFix({scope, fixId}, simplifiedResult);
private applyCodeActionCommand(args);
private getStartAndEndPosition(args, scriptInfo);
private mapCodeAction(project, {description, changes: unmappedChanges, commands});
private mapCodeAction(project, {description, changes: unmappedChanges, commands, fixId});
private mapTextChangesToCodeEdits(project, textChanges);
private mapTextChangesToCodeEditsUsingScriptinfo(textChanges, scriptInfo);
private convertTextChangeToCodeEdit(change, scriptInfo);
@@ -1,8 +1,11 @@
//// [inferObjectTypeFromStringLiteralToKeyof.ts]
declare function inference<T>(target: T, name: keyof T): void;
declare function inference1<T>(name: keyof T): T;
declare function inference2<T>(target: T, name: keyof T): T;
declare var two: "a" | "d";
inference({ a: 1, b: 2, c: 3, d(n) { return n } }, two);
const x = inference1(two);
const y = inference2({ a: 1, b: 2, c: 3, d(n) { return n } }, two);
//// [inferObjectTypeFromStringLiteralToKeyof.js]
inference({ a: 1, b: 2, c: 3, d: function (n) { return n; } }, two);
var x = inference1(two);
var y = inference2({ a: 1, b: 2, c: 3, d: function (n) { return n; } }, two);
@@ -1,22 +1,36 @@
=== tests/cases/compiler/inferObjectTypeFromStringLiteralToKeyof.ts ===
declare function inference<T>(target: T, name: keyof T): void;
>inference : Symbol(inference, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 0, 0))
>T : Symbol(T, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 0, 27))
>target : Symbol(target, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 0, 30))
>T : Symbol(T, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 0, 27))
>name : Symbol(name, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 0, 40))
>T : Symbol(T, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 0, 27))
declare function inference1<T>(name: keyof T): T;
>inference1 : Symbol(inference1, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 0, 0))
>T : Symbol(T, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 0, 28))
>name : Symbol(name, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 0, 31))
>T : Symbol(T, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 0, 28))
>T : Symbol(T, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 0, 28))
declare function inference2<T>(target: T, name: keyof T): T;
>inference2 : Symbol(inference2, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 0, 49))
>T : Symbol(T, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 1, 28))
>target : Symbol(target, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 1, 31))
>T : Symbol(T, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 1, 28))
>name : Symbol(name, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 1, 41))
>T : Symbol(T, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 1, 28))
>T : Symbol(T, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 1, 28))
declare var two: "a" | "d";
>two : Symbol(two, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 1, 11))
>two : Symbol(two, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 2, 11))
inference({ a: 1, b: 2, c: 3, d(n) { return n } }, two);
>inference : Symbol(inference, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 0, 0))
>a : Symbol(a, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 2, 11))
>b : Symbol(b, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 2, 17))
>c : Symbol(c, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 2, 23))
>d : Symbol(d, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 2, 29))
>n : Symbol(n, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 2, 32))
>n : Symbol(n, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 2, 32))
>two : Symbol(two, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 1, 11))
const x = inference1(two);
>x : Symbol(x, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 3, 5))
>inference1 : Symbol(inference1, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 0, 0))
>two : Symbol(two, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 2, 11))
const y = inference2({ a: 1, b: 2, c: 3, d(n) { return n } }, two);
>y : Symbol(y, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 4, 5))
>inference2 : Symbol(inference2, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 0, 49))
>a : Symbol(a, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 4, 22))
>b : Symbol(b, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 4, 28))
>c : Symbol(c, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 4, 34))
>d : Symbol(d, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 4, 40))
>n : Symbol(n, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 4, 43))
>n : Symbol(n, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 4, 43))
>two : Symbol(two, Decl(inferObjectTypeFromStringLiteralToKeyof.ts, 2, 11))
@@ -1,18 +1,33 @@
=== tests/cases/compiler/inferObjectTypeFromStringLiteralToKeyof.ts ===
declare function inference<T>(target: T, name: keyof T): void;
>inference : <T>(target: T, name: keyof T) => void
declare function inference1<T>(name: keyof T): T;
>inference1 : <T>(name: keyof T) => T
>T : T
>name : keyof T
>T : T
>T : T
declare function inference2<T>(target: T, name: keyof T): T;
>inference2 : <T>(target: T, name: keyof T) => T
>T : T
>target : T
>T : T
>name : keyof T
>T : T
>T : T
declare var two: "a" | "d";
>two : "a" | "d"
inference({ a: 1, b: 2, c: 3, d(n) { return n } }, two);
>inference({ a: 1, b: 2, c: 3, d(n) { return n } }, two) : void
>inference : <T>(target: T, name: keyof T) => void
const x = inference1(two);
>x : { a: any; d: any; }
>inference1(two) : { a: any; d: any; }
>inference1 : <T>(name: keyof T) => T
>two : "a" | "d"
const y = inference2({ a: 1, b: 2, c: 3, d(n) { return n } }, two);
>y : { a: number; b: number; c: number; d(n: any): any; }
>inference2({ a: 1, b: 2, c: 3, d(n) { return n } }, two) : { a: number; b: number; c: number; d(n: any): any; }
>inference2 : <T>(target: T, name: keyof T) => T
>{ a: 1, b: 2, c: 3, d(n) { return n } } : { a: number; b: number; c: number; d(n: any): any; }
>a : number
>1 : 1
@@ -552,6 +552,19 @@ class AnotherSampleClass<T> extends SampleClass<T & Foo> {
}
}
new AnotherSampleClass({});
// Positive repro from #17166
function f3<T, K extends keyof T>(t: T, k: K, tk: T[K]): void {
for (let key in t) {
key = k // ok, K ==> keyof T
t[key] = tk; // ok, T[K] ==> T[keyof T]
}
}
// # 21185
type Predicates<TaggedRecord> = {
[T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T]
}
//// [keyofAndIndexedAccess.js]
@@ -928,6 +941,13 @@ var AnotherSampleClass = /** @class */ (function (_super) {
return AnotherSampleClass;
}(SampleClass));
new AnotherSampleClass({});
// Positive repro from #17166
function f3(t, k, tk) {
for (var key in t) {
key = k; // ok, K ==> keyof T
t[key] = tk; // ok, T[K] ==> T[keyof T]
}
}
//// [keyofAndIndexedAccess.d.ts]
@@ -1188,3 +1208,7 @@ declare class AnotherSampleClass<T> extends SampleClass<T & Foo> {
constructor(props: T);
brokenMethod(): void;
}
declare function f3<T, K extends keyof T>(t: T, k: K, tk: T[K]): void;
declare type Predicates<TaggedRecord> = {
[T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T];
};
@@ -1962,3 +1962,48 @@ class AnotherSampleClass<T> extends SampleClass<T & Foo> {
new AnotherSampleClass({});
>AnotherSampleClass : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 540, 54))
// Positive repro from #17166
function f3<T, K extends keyof T>(t: T, k: K, tk: T[K]): void {
>f3 : Symbol(f3, Decl(keyofAndIndexedAccess.ts, 552, 27))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 555, 12))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 555, 14))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 555, 12))
>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 555, 34))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 555, 12))
>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 555, 39))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 555, 14))
>tk : Symbol(tk, Decl(keyofAndIndexedAccess.ts, 555, 45))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 555, 12))
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 555, 14))
for (let key in t) {
>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 556, 12))
>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 555, 34))
key = k // ok, K ==> keyof T
>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 556, 12))
>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 555, 39))
t[key] = tk; // ok, T[K] ==> T[keyof T]
>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 555, 34))
>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 556, 12))
>tk : Symbol(tk, Decl(keyofAndIndexedAccess.ts, 555, 45))
}
}
// # 21185
type Predicates<TaggedRecord> = {
>Predicates : Symbol(Predicates, Decl(keyofAndIndexedAccess.ts, 560, 1))
>TaggedRecord : Symbol(TaggedRecord, Decl(keyofAndIndexedAccess.ts, 563, 16))
[T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T]
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 564, 3))
>TaggedRecord : Symbol(TaggedRecord, Decl(keyofAndIndexedAccess.ts, 563, 16))
>variant : Symbol(variant, Decl(keyofAndIndexedAccess.ts, 564, 30))
>TaggedRecord : Symbol(TaggedRecord, Decl(keyofAndIndexedAccess.ts, 563, 16))
>TaggedRecord : Symbol(TaggedRecord, Decl(keyofAndIndexedAccess.ts, 563, 16))
>variant : Symbol(variant, Decl(keyofAndIndexedAccess.ts, 564, 30))
>TaggedRecord : Symbol(TaggedRecord, Decl(keyofAndIndexedAccess.ts, 563, 16))
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 564, 3))
}
@@ -2294,3 +2294,51 @@ new AnotherSampleClass({});
>AnotherSampleClass : typeof AnotherSampleClass
>{} : {}
// Positive repro from #17166
function f3<T, K extends keyof T>(t: T, k: K, tk: T[K]): void {
>f3 : <T, K extends keyof T>(t: T, k: K, tk: T[K]) => void
>T : T
>K : K
>T : T
>t : T
>T : T
>k : K
>K : K
>tk : T[K]
>T : T
>K : K
for (let key in t) {
>key : keyof T
>t : T
key = k // ok, K ==> keyof T
>key = k : K
>key : keyof T
>k : K
t[key] = tk; // ok, T[K] ==> T[keyof T]
>t[key] = tk : T[K]
>t[key] : T[keyof T]
>t : T
>key : keyof T
>tk : T[K]
}
}
// # 21185
type Predicates<TaggedRecord> = {
>Predicates : Predicates<TaggedRecord>
>TaggedRecord : TaggedRecord
[T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T]
>T : T
>TaggedRecord : TaggedRecord
>variant : TaggedRecord[keyof TaggedRecord]
>TaggedRecord : TaggedRecord
>TaggedRecord : TaggedRecord
>variant : any
>TaggedRecord : TaggedRecord
>T : T
}
@@ -27,11 +27,21 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(76,5): error
Type 'T' is not assignable to type 'T & U'.
Type 'T' is not assignable to type 'U'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(77,5): error TS2322: Type 'keyof (T & U)' is not assignable to type 'keyof (T | U)'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(84,9): error TS2322: Type 'keyof T' is not assignable to type 'K'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(85,9): error TS2322: Type 'T[keyof T]' is not assignable to type 'T[K]'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(86,9): error TS2322: Type 'keyof T' is not assignable to type 'K'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(88,9): error TS2322: Type 'T[keyof T]' is not assignable to type 'T[K]'.
Type 'keyof T' is not assignable to type 'K'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(91,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'.
Type 'T' is not assignable to type 'U'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(94,5): error TS2322: Type 'T[J]' is not assignable to type 'U[J]'.
Type 'T' is not assignable to type 'U'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(97,5): error TS2322: Type 'T[K]' is not assignable to type 'T[J]'.
Type 'K' is not assignable to type 'J'.
Type 'keyof T' is not assignable to type 'J'.
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(100,5): error TS2322: Type 'T[K]' is not assignable to type 'U[J]'.
Type 'T' is not assignable to type 'U'.
==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (27 errors) ====
==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (31 errors) ====
class Shape {
name: string;
width: number;
@@ -167,15 +177,42 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(85,9): error
}
// Repro from #17166
function f3<T, K extends keyof T>(obj: T, k: K, value: T[K]): void {
for (let key in obj) {
function f3<T, K extends keyof T, U extends T, J extends K>(
t: T, k: K, tk: T[K], u: U, j: J, uk: U[K], tj: T[J], uj: U[J]): void {
for (let key in t) {
key = k // ok, K ==> keyof T
k = key // error, keyof T =/=> K
~
!!! error TS2322: Type 'keyof T' is not assignable to type 'K'.
value = obj[key]; // error, T[keyof T] =/=> T[K]
~~~~~
t[key] = tk; // ok, T[K] ==> T[keyof T]
tk = t[key]; // error, T[keyof T] =/=> T[K]
~~
!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'T[K]'.
!!! error TS2322: Type 'keyof T' is not assignable to type 'K'.
}
}
tk = uk;
uk = tk; // error
~~
!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'.
!!! error TS2322: Type 'T' is not assignable to type 'U'.
tj = uj;
uj = tj; // error
~~
!!! error TS2322: Type 'T[J]' is not assignable to type 'U[J]'.
!!! error TS2322: Type 'T' is not assignable to type 'U'.
tk = tj;
tj = tk; // error
~~
!!! error TS2322: Type 'T[K]' is not assignable to type 'T[J]'.
!!! error TS2322: Type 'K' is not assignable to type 'J'.
!!! error TS2322: Type 'keyof T' is not assignable to type 'J'.
tk = uj;
uj = tk; // error
~~
!!! error TS2322: Type 'T[K]' is not assignable to type 'U[J]'.
!!! error TS2322: Type 'T' is not assignable to type 'U'.
}
@@ -80,13 +80,26 @@ function f20<T, U>(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) {
}
// Repro from #17166
function f3<T, K extends keyof T>(obj: T, k: K, value: T[K]): void {
for (let key in obj) {
function f3<T, K extends keyof T, U extends T, J extends K>(
t: T, k: K, tk: T[K], u: U, j: J, uk: U[K], tj: T[J], uj: U[J]): void {
for (let key in t) {
key = k // ok, K ==> keyof T
k = key // error, keyof T =/=> K
value = obj[key]; // error, T[keyof T] =/=> T[K]
t[key] = tk; // ok, T[K] ==> T[keyof T]
tk = t[key]; // error, T[keyof T] =/=> T[K]
}
}
tk = uk;
uk = tk; // error
tj = uj;
uj = tj; // error
tk = tj;
tj = tk; // error
tk = uj;
uj = tk; // error
}
//// [keyofAndIndexedAccessErrors.js]
@@ -120,9 +133,19 @@ function f20(k1, k2, o1, o2) {
k2 = k1;
}
// Repro from #17166
function f3(obj, k, value) {
for (var key in obj) {
function f3(t, k, tk, u, j, uk, tj, uj) {
for (var key in t) {
key = k; // ok, K ==> keyof T
k = key; // error, keyof T =/=> K
value = obj[key]; // error, T[keyof T] =/=> T[K]
t[key] = tk; // ok, T[K] ==> T[keyof T]
tk = t[key]; // error, T[keyof T] =/=> T[K]
}
tk = uk;
uk = tk; // error
tj = uj;
uj = tj; // error
tk = tj;
tj = tk; // error
tk = uj;
uj = tk; // error
}
@@ -270,32 +270,90 @@ function f20<T, U>(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) {
}
// Repro from #17166
function f3<T, K extends keyof T>(obj: T, k: K, value: T[K]): void {
function f3<T, K extends keyof T, U extends T, J extends K>(
>f3 : Symbol(f3, Decl(keyofAndIndexedAccessErrors.ts, 78, 1))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12))
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12))
>obj : Symbol(obj, Decl(keyofAndIndexedAccessErrors.ts, 81, 34))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12))
>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 81, 41))
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14))
>value : Symbol(value, Decl(keyofAndIndexedAccessErrors.ts, 81, 47))
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 33))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12))
>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 46))
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14))
for (let key in obj) {
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 82, 12))
>obj : Symbol(obj, Decl(keyofAndIndexedAccessErrors.ts, 81, 34))
t: T, k: K, tk: T[K], u: U, j: J, uk: U[K], tj: T[J], uj: U[J]): void {
>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 60))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12))
>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 82, 9))
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14))
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12))
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14))
>u : Symbol(u, Decl(keyofAndIndexedAccessErrors.ts, 82, 25))
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 33))
>j : Symbol(j, Decl(keyofAndIndexedAccessErrors.ts, 82, 31))
>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 46))
>uk : Symbol(uk, Decl(keyofAndIndexedAccessErrors.ts, 82, 37))
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 33))
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14))
>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47))
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12))
>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 46))
>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57))
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 33))
>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 46))
for (let key in t) {
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12))
>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 60))
key = k // ok, K ==> keyof T
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12))
>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 82, 9))
k = key // error, keyof T =/=> K
>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 81, 41))
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 82, 12))
>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 82, 9))
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12))
value = obj[key]; // error, T[keyof T] =/=> T[K]
>value : Symbol(value, Decl(keyofAndIndexedAccessErrors.ts, 81, 47))
>obj : Symbol(obj, Decl(keyofAndIndexedAccessErrors.ts, 81, 34))
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 82, 12))
t[key] = tk; // ok, T[K] ==> T[keyof T]
>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 60))
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12))
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
tk = t[key]; // error, T[keyof T] =/=> T[K]
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 60))
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12))
}
tk = uk;
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
>uk : Symbol(uk, Decl(keyofAndIndexedAccessErrors.ts, 82, 37))
uk = tk; // error
>uk : Symbol(uk, Decl(keyofAndIndexedAccessErrors.ts, 82, 37))
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
tj = uj;
>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47))
>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57))
uj = tj; // error
>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57))
>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47))
tk = tj;
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47))
tj = tk; // error
>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47))
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
tk = uj;
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57))
uj = tk; // error
>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57))
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
}
@@ -301,35 +301,104 @@ function f20<T, U>(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) {
}
// Repro from #17166
function f3<T, K extends keyof T>(obj: T, k: K, value: T[K]): void {
>f3 : <T, K extends keyof T>(obj: T, k: K, value: T[K]) => void
function f3<T, K extends keyof T, U extends T, J extends K>(
>f3 : <T, K extends keyof T, U extends T, J extends K>(t: T, k: K, tk: T[K], u: U, j: J, uk: U[K], tj: T[J], uj: U[J]) => void
>T : T
>K : K
>T : T
>obj : T
>U : U
>T : T
>J : J
>K : K
t: T, k: K, tk: T[K], u: U, j: J, uk: U[K], tj: T[J], uj: U[J]): void {
>t : T
>T : T
>k : K
>K : K
>value : T[K]
>tk : T[K]
>T : T
>K : K
>u : U
>U : U
>j : J
>J : J
>uk : U[K]
>U : U
>K : K
>tj : T[J]
>T : T
>J : J
>uj : U[J]
>U : U
>J : J
for (let key in obj) {
for (let key in t) {
>key : keyof T
>obj : T
>t : T
key = k // ok, K ==> keyof T
>key = k : K
>key : keyof T
>k : K
k = key // error, keyof T =/=> K
>k = key : keyof T
>k : K
>key : keyof T
value = obj[key]; // error, T[keyof T] =/=> T[K]
>value = obj[key] : T[keyof T]
>value : T[K]
>obj[key] : T[keyof T]
>obj : T
t[key] = tk; // ok, T[K] ==> T[keyof T]
>t[key] = tk : T[K]
>t[key] : T[keyof T]
>t : T
>key : keyof T
>tk : T[K]
tk = t[key]; // error, T[keyof T] =/=> T[K]
>tk = t[key] : T[keyof T]
>tk : T[K]
>t[key] : T[keyof T]
>t : T
>key : keyof T
}
tk = uk;
>tk = uk : U[K]
>tk : T[K]
>uk : U[K]
uk = tk; // error
>uk = tk : T[K]
>uk : U[K]
>tk : T[K]
tj = uj;
>tj = uj : U[J]
>tj : T[J]
>uj : U[J]
uj = tj; // error
>uj = tj : T[J]
>uj : U[J]
>tj : T[J]
tk = tj;
>tk = tj : T[J]
>tk : T[K]
>tj : T[J]
tj = tk; // error
>tj = tk : T[K]
>tj : T[J]
>tk : T[K]
tk = uj;
>tk = uj : U[J]
>tk : T[K]
>uj : U[J]
uj = tk; // error
>uj = tk : T[K]
>uj : U[J]
>tk : T[K]
}
@@ -0,0 +1,8 @@
tests/cases/compiler/objectBindingPattern_restElementWithPropertyName.ts(1,15): error TS2566: A rest element cannot have a property name.
==== tests/cases/compiler/objectBindingPattern_restElementWithPropertyName.ts (1 errors) ====
const { ...a: b } = {};
~
!!! error TS2566: A rest element cannot have a property name.
@@ -0,0 +1,15 @@
//// [objectBindingPattern_restElementWithPropertyName.ts]
const { ...a: b } = {};
//// [objectBindingPattern_restElementWithPropertyName.js]
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
t[p[i]] = s[p[i]];
return t;
};
var b = __rest({}, []);
@@ -0,0 +1,4 @@
=== tests/cases/compiler/objectBindingPattern_restElementWithPropertyName.ts ===
const { ...a: b } = {};
>b : Symbol(b, Decl(objectBindingPattern_restElementWithPropertyName.ts, 0, 7))
@@ -0,0 +1,6 @@
=== tests/cases/compiler/objectBindingPattern_restElementWithPropertyName.ts ===
const { ...a: b } = {};
>a : any
>b : {}
>{} : {}
@@ -63,7 +63,7 @@
],
"documentation": [
{
"text": "DocT} A template",
"text": "Doc",
"kind": "text"
}
],
@@ -76,6 +76,10 @@
"name": "augments",
"text": "C<T> Augments it"
},
{
"name": "template",
"text": "{T} A template"
},
{
"name": "type",
"text": "{number | string} A type"
@@ -0,0 +1,11 @@
//// [reverseMappedContravariantInference.ts]
// Repro from #21273
declare function conforms<T>(source: { [K in keyof T]: (val: T[K]) => boolean }): (value: T) => boolean;
conforms({ foo: (v: string) => false })({ foo: "hello" });
//// [reverseMappedContravariantInference.js]
"use strict";
// Repro from #21273
conforms({ foo: function (v) { return false; } })({ foo: "hello" });
@@ -0,0 +1,21 @@
=== tests/cases/compiler/reverseMappedContravariantInference.ts ===
// Repro from #21273
declare function conforms<T>(source: { [K in keyof T]: (val: T[K]) => boolean }): (value: T) => boolean;
>conforms : Symbol(conforms, Decl(reverseMappedContravariantInference.ts, 0, 0))
>T : Symbol(T, Decl(reverseMappedContravariantInference.ts, 2, 26))
>source : Symbol(source, Decl(reverseMappedContravariantInference.ts, 2, 29))
>K : Symbol(K, Decl(reverseMappedContravariantInference.ts, 2, 40))
>T : Symbol(T, Decl(reverseMappedContravariantInference.ts, 2, 26))
>val : Symbol(val, Decl(reverseMappedContravariantInference.ts, 2, 56))
>T : Symbol(T, Decl(reverseMappedContravariantInference.ts, 2, 26))
>K : Symbol(K, Decl(reverseMappedContravariantInference.ts, 2, 40))
>value : Symbol(value, Decl(reverseMappedContravariantInference.ts, 2, 83))
>T : Symbol(T, Decl(reverseMappedContravariantInference.ts, 2, 26))
conforms({ foo: (v: string) => false })({ foo: "hello" });
>conforms : Symbol(conforms, Decl(reverseMappedContravariantInference.ts, 0, 0))
>foo : Symbol(foo, Decl(reverseMappedContravariantInference.ts, 3, 10))
>v : Symbol(v, Decl(reverseMappedContravariantInference.ts, 3, 17))
>foo : Symbol(foo, Decl(reverseMappedContravariantInference.ts, 3, 41))
@@ -0,0 +1,28 @@
=== tests/cases/compiler/reverseMappedContravariantInference.ts ===
// Repro from #21273
declare function conforms<T>(source: { [K in keyof T]: (val: T[K]) => boolean }): (value: T) => boolean;
>conforms : <T>(source: { [K in keyof T]: (val: T[K]) => boolean; }) => (value: T) => boolean
>T : T
>source : { [K in keyof T]: (val: T[K]) => boolean; }
>K : K
>T : T
>val : T[K]
>T : T
>K : K
>value : T
>T : T
conforms({ foo: (v: string) => false })({ foo: "hello" });
>conforms({ foo: (v: string) => false })({ foo: "hello" }) : boolean
>conforms({ foo: (v: string) => false }) : (value: { foo: any; }) => boolean
>conforms : <T>(source: { [K in keyof T]: (val: T[K]) => boolean; }) => (value: T) => boolean
>{ foo: (v: string) => false } : { foo: (v: string) => boolean; }
>foo : (v: string) => boolean
>(v: string) => false : (v: string) => boolean
>v : string
>false : false
>{ foo: "hello" } : { foo: string; }
>foo : string
>"hello" : "hello"
@@ -0,0 +1,60 @@
tests/cases/compiler/strictNullEmptyDestructuring.ts(3,5): error TS2531: Object is possibly 'null'.
tests/cases/compiler/strictNullEmptyDestructuring.ts(5,5): error TS2531: Object is possibly 'null'.
tests/cases/compiler/strictNullEmptyDestructuring.ts(7,2): error TS2531: Object is possibly 'null'.
tests/cases/compiler/strictNullEmptyDestructuring.ts(9,5): error TS2532: Object is possibly 'undefined'.
tests/cases/compiler/strictNullEmptyDestructuring.ts(11,2): error TS2532: Object is possibly 'undefined'.
tests/cases/compiler/strictNullEmptyDestructuring.ts(13,5): error TS2531: Object is possibly 'null'.
tests/cases/compiler/strictNullEmptyDestructuring.ts(15,2): error TS2531: Object is possibly 'null'.
tests/cases/compiler/strictNullEmptyDestructuring.ts(17,5): error TS2532: Object is possibly 'undefined'.
tests/cases/compiler/strictNullEmptyDestructuring.ts(19,2): error TS2532: Object is possibly 'undefined'.
tests/cases/compiler/strictNullEmptyDestructuring.ts(21,5): error TS2533: Object is possibly 'null' or 'undefined'.
tests/cases/compiler/strictNullEmptyDestructuring.ts(23,2): error TS2533: Object is possibly 'null' or 'undefined'.
==== tests/cases/compiler/strictNullEmptyDestructuring.ts (11 errors) ====
// Repro from #20873
let [] = null;
~~
!!! error TS2531: Object is possibly 'null'.
let { } = null;
~~~
!!! error TS2531: Object is possibly 'null'.
({} = null);
~~
!!! error TS2531: Object is possibly 'null'.
let { } = undefined;
~~~
!!! error TS2532: Object is possibly 'undefined'.
({} = undefined);
~~
!!! error TS2532: Object is possibly 'undefined'.
let { } = Math.random() ? {} : null;
~~~
!!! error TS2531: Object is possibly 'null'.
({} = Math.random() ? {} : null);
~~
!!! error TS2531: Object is possibly 'null'.
let { } = Math.random() ? {} : undefined;
~~~
!!! error TS2532: Object is possibly 'undefined'.
({} = Math.random() ? {} : undefined);
~~
!!! error TS2532: Object is possibly 'undefined'.
let { } = Math.random() ? null : undefined;
~~~
!!! error TS2533: Object is possibly 'null' or 'undefined'.
({} = Math.random() ? null : undefined);
~~
!!! error TS2533: Object is possibly 'null' or 'undefined'.
@@ -0,0 +1,39 @@
//// [strictNullEmptyDestructuring.ts]
// Repro from #20873
let [] = null;
let { } = null;
({} = null);
let { } = undefined;
({} = undefined);
let { } = Math.random() ? {} : null;
({} = Math.random() ? {} : null);
let { } = Math.random() ? {} : undefined;
({} = Math.random() ? {} : undefined);
let { } = Math.random() ? null : undefined;
({} = Math.random() ? null : undefined);
//// [strictNullEmptyDestructuring.js]
// Repro from #20873
var _a = null;
var _b = null;
(null);
var _c = undefined;
(undefined);
var _d = Math.random() ? {} : null;
(Math.random() ? {} : null);
var _e = Math.random() ? {} : undefined;
(Math.random() ? {} : undefined);
var _f = Math.random() ? null : undefined;
(Math.random() ? null : undefined);
@@ -0,0 +1,49 @@
=== tests/cases/compiler/strictNullEmptyDestructuring.ts ===
// Repro from #20873
let [] = null;
let { } = null;
({} = null);
let { } = undefined;
>undefined : Symbol(undefined)
({} = undefined);
>undefined : Symbol(undefined)
let { } = Math.random() ? {} : null;
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
({} = Math.random() ? {} : null);
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
let { } = Math.random() ? {} : undefined;
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
>undefined : Symbol(undefined)
({} = Math.random() ? {} : undefined);
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
>undefined : Symbol(undefined)
let { } = Math.random() ? null : undefined;
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
>undefined : Symbol(undefined)
({} = Math.random() ? null : undefined);
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
>undefined : Symbol(undefined)
@@ -0,0 +1,87 @@
=== tests/cases/compiler/strictNullEmptyDestructuring.ts ===
// Repro from #20873
let [] = null;
>null : null
let { } = null;
>null : null
({} = null);
>({} = null) : any
>{} = null : any
>{} : {}
>null : null
let { } = undefined;
>undefined : undefined
({} = undefined);
>({} = undefined) : any
>{} = undefined : any
>{} : {}
>undefined : undefined
let { } = Math.random() ? {} : null;
>Math.random() ? {} : null : {} | null
>Math.random() : number
>Math.random : () => number
>Math : Math
>random : () => number
>{} : {}
>null : null
({} = Math.random() ? {} : null);
>({} = Math.random() ? {} : null) : {}
>{} = Math.random() ? {} : null : {}
>{} : {}
>Math.random() ? {} : null : {} | null
>Math.random() : number
>Math.random : () => number
>Math : Math
>random : () => number
>{} : {}
>null : null
let { } = Math.random() ? {} : undefined;
>Math.random() ? {} : undefined : {} | undefined
>Math.random() : number
>Math.random : () => number
>Math : Math
>random : () => number
>{} : {}
>undefined : undefined
({} = Math.random() ? {} : undefined);
>({} = Math.random() ? {} : undefined) : {}
>{} = Math.random() ? {} : undefined : {}
>{} : {}
>Math.random() ? {} : undefined : {} | undefined
>Math.random() : number
>Math.random : () => number
>Math : Math
>random : () => number
>{} : {}
>undefined : undefined
let { } = Math.random() ? null : undefined;
>Math.random() ? null : undefined : null | undefined
>Math.random() : number
>Math.random : () => number
>Math : Math
>random : () => number
>null : null
>undefined : undefined
({} = Math.random() ? null : undefined);
>({} = Math.random() ? null : undefined) : any
>{} = Math.random() ? null : undefined : any
>{} : {}
>Math.random() ? null : undefined : null | undefined
>Math.random() : number
>Math.random : () => number
>Math : Math
>random : () => number
>null : null
>undefined : undefined
File diff suppressed because it is too large Load Diff
+5 -6
View File
@@ -1,11 +1,10 @@
Exit Code: 1
Standard output:
node_modules/rxjs/scheduler/VirtualTimeScheduler.d.ts(22,22): error TS2415: Class 'VirtualAction<T>' incorrectly extends base class 'AsyncAction<T>'.
Types of property 'work' are incompatible.
Type '(this: VirtualAction<T>, state?: T | undefined) => void' is not assignable to type '(this: AsyncAction<T>, state?: T | undefined) => void'.
The 'this' types of each signature are incompatible.
Type 'AsyncAction<T>' is not assignable to type 'VirtualAction<T>'.
Property 'index' is missing in type 'AsyncAction<T>'.
node_modules/rxjs/scheduler/VirtualTimeScheduler.d.ts(24,15): error TS2416: Property 'work' in type 'VirtualAction<T>' is not assignable to the same property in base type 'AsyncAction<T>'.
Type '(this: VirtualAction<T>, state?: T | undefined) => void' is not assignable to type '(this: AsyncAction<T>, state?: T | undefined) => void'.
The 'this' types of each signature are incompatible.
Type 'AsyncAction<T>' is not assignable to type 'VirtualAction<T>'.
Property 'index' is missing in type 'AsyncAction<T>'.
+8
View File
@@ -0,0 +1,8 @@
Exit Code: 1
Standard output:
node_modules/sift/index.d.ts(22,54): error TS2344: Type 'T[0][index]' does not satisfy the constraint 'any[]'.
node_modules/sift/index.d.ts(32,35): error TS2344: Type 'T[0][P]' does not satisfy the constraint 'any[]'.
Standard error:
@@ -1,3 +1,5 @@
declare function inference<T>(target: T, name: keyof T): void;
declare function inference1<T>(name: keyof T): T;
declare function inference2<T>(target: T, name: keyof T): T;
declare var two: "a" | "d";
inference({ a: 1, b: 2, c: 3, d(n) { return n } }, two);
const x = inference1(two);
const y = inference2({ a: 1, b: 2, c: 3, d(n) { return n } }, two);
@@ -0,0 +1 @@
const { ...a: b } = {};
@@ -0,0 +1,6 @@
// @strict: true
// Repro from #21273
declare function conforms<T>(source: { [K in keyof T]: (val: T[K]) => boolean }): (value: T) => boolean;
conforms({ foo: (v: string) => false })({ foo: "hello" });
@@ -0,0 +1,25 @@
// @strictNullChecks: true
// Repro from #20873
let [] = null;
let { } = null;
({} = null);
let { } = undefined;
({} = undefined);
let { } = Math.random() ? {} : null;
({} = Math.random() ? {} : null);
let { } = Math.random() ? {} : undefined;
({} = Math.random() ? {} : undefined);
let { } = Math.random() ? null : undefined;
({} = Math.random() ? null : undefined);
@@ -554,3 +554,16 @@ class AnotherSampleClass<T> extends SampleClass<T & Foo> {
}
}
new AnotherSampleClass({});
// Positive repro from #17166
function f3<T, K extends keyof T>(t: T, k: K, tk: T[K]): void {
for (let key in t) {
key = k // ok, K ==> keyof T
t[key] = tk; // ok, T[K] ==> T[keyof T]
}
}
// # 21185
type Predicates<TaggedRecord> = {
[T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T]
}
@@ -79,10 +79,23 @@ function f20<T, U>(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) {
}
// Repro from #17166
function f3<T, K extends keyof T>(obj: T, k: K, value: T[K]): void {
for (let key in obj) {
function f3<T, K extends keyof T, U extends T, J extends K>(
t: T, k: K, tk: T[K], u: U, j: J, uk: U[K], tj: T[J], uj: U[J]): void {
for (let key in t) {
key = k // ok, K ==> keyof T
k = key // error, keyof T =/=> K
value = obj[key]; // error, T[keyof T] =/=> T[K]
t[key] = tk; // ok, T[K] ==> T[keyof T]
tk = t[key]; // error, T[keyof T] =/=> T[K]
}
}
tk = uk;
uk = tk; // error
tj = uj;
uj = tj; // error
tk = tj;
tj = tk; // error
tk = uj;
uj = tk; // error
}
@@ -11,12 +11,12 @@ public testMethod( )
}`);
// We're missing scenarios of formatting option settings due to bug 693273 - [TypeScript] Need to improve fourslash support for formatting options.
// Missing scenario ** Uncheck Tools->Options->Text Editor->TypeScript->Formatting->General->Format on paste **
//verify.currentFileContentIs("module TestModule {\r\n\
// class TestClass{\r\n\
//private foo;\r\n\
//public testMethod( )\r\n\
//{}\r\n\
//}\r\n\
//verify.currentFileContentIs("module TestModule {\n\
// class TestClass{\n\
//private foo;\n\
//public testMethod( )\n\
//{}\n\
//}\n\
//}");
// Missing scenario ** Check Tools->Options->Text Editor->TypeScript->Formatting->General->Format on paste **
verify.currentFileContentIs(`module TestModule {
@@ -12,6 +12,6 @@
verify.quickInfoAt("className", "class Sphere");
goTo.marker('interfaceGoesHere');
edit.insert("\r\ninterface Surface {\r\n reflect: () => number;\r\n}\r\n");
edit.insert("\ninterface Surface {\n reflect: () => number;\n}\n");
verify.quickInfoAt("className", "class Sphere");
@@ -9,9 +9,8 @@
verify.codeFix({
description: "Declare property 'foo'",
index: 0,
// TODO: GH#18445
newFileContent: `class C {
foo: number;\r
foo: number;
method() {
this.foo = 10;
}
@@ -9,9 +9,8 @@
verify.codeFix({
description: "Add index signature for property 'foo'",
index: 1,
// TODO: GH#18445
newFileContent: `class C {
[x: string]: number;\r
[x: string]: number;
method() {
this.foo = 10;
}
@@ -9,9 +9,8 @@
verify.codeFix({
description: "Declare static property 'foo'",
index: 0,
// TODO: GH#18445
newFileContent: `class C {
static foo: number;\r
static foo: number;
static method() {
this.foo = 10;
}
@@ -15,10 +15,9 @@
verify.codeFix({
description: "Initialize property 'foo' in the constructor",
index: 0,
// TODO: GH#18445
newFileContent: `class C {
constructor() {\r
this.foo = undefined;\r
constructor() {
this.foo = undefined;
}
method() {
this.foo === 10;
@@ -13,12 +13,11 @@
verify.codeFix({
description: "Initialize static property 'foo'",
index: 0,
// TODO: GH#18445
newFileContent: `class C {
static method() {
()=>{ this.foo === 10 };
}
}\r
C.foo = undefined;\r
}
C.foo = undefined;
`
});
@@ -13,10 +13,9 @@
verify.codeFix({
description: "Initialize property 'foo' in the constructor",
index: 0,
// TODO: GH#18445
newFileContent: `class C {
constructor() {\r
this.foo = undefined;\r
constructor() {
this.foo = undefined;
}
prop = ()=>{ this.foo === 10 };
}`
@@ -11,10 +11,9 @@
verify.codeFix({
description: "Initialize static property 'foo'",
index: 2,
// TODO: GH#18445
newFileContent: `class C {
static p = ()=>{ this.foo === 10 };
}\r
C.foo = undefined;\r
}
C.foo = undefined;
`
});
@@ -11,12 +11,11 @@
verify.codeFixAll({
fixId: "addMissingMember",
newFileContent:
// TODO: GH#18445
`class C {
x: number;\r
y(): any {\r
throw new Error("Method not implemented.");\r
}\r
x: number;
y(): any {
throw new Error("Method not implemented.");
}
method() {
this.x = 0;
this.y();
@@ -16,13 +16,12 @@
verify.codeFixAll({
fixId: "addMissingMember",
newFileContent:
// TODO: GH#18445
`class C {
y() {\r
throw new Error("Method not implemented.");\r
}\r
constructor() {\r
this.x = undefined;\r
y() {
throw new Error("Method not implemented.");
}
constructor() {
this.x = undefined;
}
method() {
this.x;
@@ -12,9 +12,9 @@ verify.codeFix({
`class A {
f() {}
}
let B = class implements A {\r
f(): void {\r
throw new Error("Method not implemented.");\r
}\r
let B = class implements A {
f(): void {
throw new Error("Method not implemented.");
}
}`
});
@@ -20,7 +20,7 @@ verify.codeFix({
return C;
}
let B = class extends foo("s")<number> {\r
a: string | number;\r
let B = class extends foo("s")<number> {
a: string | number;
}`
});
@@ -20,7 +20,7 @@ verify.codeFix({
return C;
}
class B extends foo("s")<number> {\r
a: string | number;\r
class B extends foo("s")<number> {
a: string | number;
}`
});
@@ -42,13 +42,13 @@ verify.codeFix({
// Don't need to add anything in this case.
abstract class B extends A {}
class C extends A {\r
a: string | number;\r
b: this;\r
c: A;\r
d: string | number;\r
e: this;\r
f: A;\r
g: string;\r
class C extends A {
a: string | number;
b: this;
c: A;
d: string | number;
e: this;
f: A;
g: string;
}`
});
@@ -22,16 +22,16 @@ verify.codeFix({
abstract foo(): number;
}
class C extends A {\r
f(a: number, b: string): boolean;\r
f(a: number, b: string): this;\r
f(a: string, b: number): Function;\r
f(a: string): Function;\r
f(a: any, b?: any) {\r
throw new Error("Method not implemented.");\r
}\r
foo(): number {\r
throw new Error("Method not implemented.");\r
}\r
class C extends A {
f(a: number, b: string): boolean;
f(a: number, b: string): this;
f(a: string, b: number): Function;
f(a: string): Function;
f(a: any, b?: any) {
throw new Error("Method not implemented.");
}
foo(): number {
throw new Error("Method not implemented.");
}
}`
});
@@ -14,9 +14,9 @@ verify.codeFix({
abstract f(): this;
}
class C extends A {\r
f(): this {\r
throw new Error("Method not implemented.");\r
}\r
class C extends A {
f(): this {
throw new Error("Method not implemented.");
}
}`
});
@@ -14,9 +14,9 @@ verify.codeFix({
abstract f(x: T): T;
}
class C extends A<number> {\r
f(x: number): number {\r
throw new Error("Method not implemented.");\r
}\r
class C extends A<number> {
f(x: number): number {
throw new Error("Method not implemented.");
}
}`
});
@@ -14,9 +14,9 @@ verify.codeFix({
abstract f(x: T): T;
}
class C<U> extends A<U> {\r
f(x: U): U {\r
throw new Error("Method not implemented.");\r
}\r
class C<U> extends A<U> {
f(x: U): U {
throw new Error("Method not implemented.");
}
}`
});
@@ -8,19 +8,18 @@
verify.codeFixAll({
fixId: "fixClassDoesntImplementInheritedAbstractMember",
// TODO: GH#18445
newFileContent:
`abstract class A {
abstract m(): void;
}
class B extends A {\r
m(): void {\r
throw new Error("Method not implemented.");\r
}\r
class B extends A {
m(): void {
throw new Error("Method not implemented.");
}
}
class C extends A {\r
m(): void {\r
throw new Error("Method not implemented.");\r
}\r
class C extends A {
m(): void {
throw new Error("Method not implemented.");
}
}`,
});
@@ -18,9 +18,9 @@ verify.codeFix({
abstract z: A;
}
class C extends A {\r
x: number;\r
y: this;\r
z: A;\r
class C extends A {
x: number;
y: this;
z: A;
}`
});

Some files were not shown because too many files have changed in this diff Show More