mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Add quick fix to add 'void' to Promise resolved without value (#40558)
* Add codefix to add 'void' to Promise resolved without value * Add specific error message in checker to reduce quick-fix time in editor
This commit is contained in:
parent
7db91182f7
commit
dba042d7d5
@ -26708,6 +26708,22 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function isPromiseResolveArityError(node: CallLikeExpression) {
|
||||
if (!isCallExpression(node) || !isIdentifier(node.expression)) return false;
|
||||
|
||||
const symbol = resolveName(node.expression, node.expression.escapedText, SymbolFlags.Value, undefined, undefined, false);
|
||||
const decl = symbol?.valueDeclaration;
|
||||
if (!decl || !isParameter(decl) || !isFunctionExpressionOrArrowFunction(decl.parent) || !isNewExpression(decl.parent.parent) || !isIdentifier(decl.parent.parent.expression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const globalPromiseSymbol = getGlobalPromiseConstructorSymbol(/*reportErrors*/ false);
|
||||
if (!globalPromiseSymbol) return false;
|
||||
|
||||
const constructorSymbol = getSymbolAtLocation(decl.parent.parent.expression, /*ignoreErrors*/ true);
|
||||
return constructorSymbol === globalPromiseSymbol;
|
||||
}
|
||||
|
||||
function getArgumentArityError(node: CallLikeExpression, signatures: readonly Signature[], args: readonly Expression[]) {
|
||||
let min = Number.POSITIVE_INFINITY;
|
||||
let max = Number.NEGATIVE_INFINITY;
|
||||
@ -26740,9 +26756,15 @@ namespace ts {
|
||||
let spanArray: NodeArray<Node>;
|
||||
let related: DiagnosticWithLocation | undefined;
|
||||
|
||||
const error = hasRestParameter || hasSpreadArgument ? hasRestParameter && hasSpreadArgument ? Diagnostics.Expected_at_least_0_arguments_but_got_1_or_more :
|
||||
hasRestParameter ? Diagnostics.Expected_at_least_0_arguments_but_got_1 :
|
||||
Diagnostics.Expected_0_arguments_but_got_1_or_more : Diagnostics.Expected_0_arguments_but_got_1;
|
||||
const error = hasRestParameter || hasSpreadArgument ?
|
||||
hasRestParameter && hasSpreadArgument ?
|
||||
Diagnostics.Expected_at_least_0_arguments_but_got_1_or_more :
|
||||
hasRestParameter ?
|
||||
Diagnostics.Expected_at_least_0_arguments_but_got_1 :
|
||||
Diagnostics.Expected_0_arguments_but_got_1_or_more :
|
||||
paramRange === 1 && argCount === 0 && isPromiseResolveArityError(node) ?
|
||||
Diagnostics.Expected_0_arguments_but_got_1_Did_you_forget_to_include_void_in_your_type_argument_to_Promise :
|
||||
Diagnostics.Expected_0_arguments_but_got_1;
|
||||
|
||||
if (closestSignature && getMinArgumentCount(closestSignature) > argCount && closestSignature.declaration) {
|
||||
const paramDecl = closestSignature.declaration.parameters[closestSignature.thisParameter ? argCount + 1 : argCount];
|
||||
|
||||
@ -3039,6 +3039,10 @@
|
||||
"category": "Error",
|
||||
"code": 2793
|
||||
},
|
||||
"Expected {0} arguments, but got {1}. Did you forget to include 'void' in your type argument to 'Promise'?": {
|
||||
"category": "Error",
|
||||
"code": 2794
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
@ -5927,6 +5931,14 @@
|
||||
"category": "Message",
|
||||
"code": 95142
|
||||
},
|
||||
"Add 'void' to Promise resolved without a value": {
|
||||
"category": "Message",
|
||||
"code": 95143
|
||||
},
|
||||
"Add 'void' to all Promises resolved without a value": {
|
||||
"category": "Message",
|
||||
"code": 95144
|
||||
},
|
||||
|
||||
"No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer.": {
|
||||
"category": "Error",
|
||||
|
||||
@ -339,17 +339,23 @@ namespace FourSlash {
|
||||
this.languageServiceAdapterHost.addScript(fileName, file, /*isRootFile*/ true);
|
||||
}
|
||||
});
|
||||
if (!compilationOptions.noLib) {
|
||||
this.languageServiceAdapterHost.addScript(Harness.Compiler.defaultLibFileName,
|
||||
Harness.Compiler.getDefaultLibrarySourceFile()!.text, /*isRootFile*/ false);
|
||||
|
||||
compilationOptions.lib?.forEach(fileName => {
|
||||
if (!compilationOptions.noLib) {
|
||||
const seen = new Set<string>();
|
||||
const addSourceFile = (fileName: string) => {
|
||||
if (seen.has(fileName)) return;
|
||||
seen.add(fileName);
|
||||
const libFile = Harness.Compiler.getDefaultLibrarySourceFile(fileName);
|
||||
ts.Debug.assertIsDefined(libFile, `Could not find lib file '${fileName}'`);
|
||||
if (libFile) {
|
||||
this.languageServiceAdapterHost.addScript(fileName, libFile.text, /*isRootFile*/ false);
|
||||
this.languageServiceAdapterHost.addScript(fileName, libFile.text, /*isRootFile*/ false);
|
||||
if (!ts.some(libFile.libReferenceDirectives)) return;
|
||||
for (const directive of libFile.libReferenceDirectives) {
|
||||
addSourceFile(`lib.${directive.fileName}.d.ts`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
addSourceFile(Harness.Compiler.defaultLibFileName);
|
||||
compilationOptions.lib?.forEach(addSourceFile);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3878,7 +3884,7 @@ namespace FourSlash {
|
||||
const testData = parseTestData(absoluteBasePath, content, absoluteFileName);
|
||||
const state = new TestState(absoluteFileName, absoluteBasePath, testType, testData);
|
||||
const actualFileName = Harness.IO.resolvePath(fileName) || absoluteFileName;
|
||||
const output = ts.transpileModule(content, { reportDiagnostics: true, fileName: actualFileName, compilerOptions: { target: ts.ScriptTarget.ES2015, inlineSourceMap: true } });
|
||||
const output = ts.transpileModule(content, { reportDiagnostics: true, fileName: actualFileName, compilerOptions: { target: ts.ScriptTarget.ES2015, inlineSourceMap: true, inlineSources: true } });
|
||||
if (output.diagnostics!.length > 0) {
|
||||
throw new Error(`Syntax error in ${absoluteBasePath}: ${output.diagnostics![0].messageText}`);
|
||||
}
|
||||
@ -3888,7 +3894,7 @@ namespace FourSlash {
|
||||
function runCode(code: string, state: TestState, fileName: string): void {
|
||||
// Compile and execute the test
|
||||
const generatedFile = ts.changeExtension(fileName, ".js");
|
||||
const wrappedCode = `(function(test, goTo, plugins, verify, edit, debug, format, cancellation, classification, completion, verifyOperationIsCancelled) {${code}\n//# sourceURL=${generatedFile}\n})`;
|
||||
const wrappedCode = `(function(test, goTo, plugins, verify, edit, debug, format, cancellation, classification, completion, verifyOperationIsCancelled) {${code}\n//# sourceURL=${ts.getBaseFileName(generatedFile)}\n})`;
|
||||
|
||||
type SourceMapSupportModule = typeof import("source-map-support") & {
|
||||
// TODO(rbuckton): This is missing from the DT definitions and needs to be added.
|
||||
|
||||
82
src/services/codefixes/fixAddVoidToPromise.ts
Normal file
82
src/services/codefixes/fixAddVoidToPromise.ts
Normal file
@ -0,0 +1,82 @@
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
const fixName = "addVoidToPromise";
|
||||
const fixId = "addVoidToPromise";
|
||||
const errorCodes = [
|
||||
Diagnostics.Expected_0_arguments_but_got_1_Did_you_forget_to_include_void_in_your_type_argument_to_Promise.code
|
||||
];
|
||||
registerCodeFix({
|
||||
errorCodes,
|
||||
fixIds: [fixId],
|
||||
getCodeActions(context) {
|
||||
const changes = textChanges.ChangeTracker.with(context, t => makeChange(t, context.sourceFile, context.span, context.program));
|
||||
if (changes.length > 0) {
|
||||
return [createCodeFixAction(fixName, changes, Diagnostics.Add_void_to_Promise_resolved_without_a_value, fixId, Diagnostics.Add_void_to_all_Promises_resolved_without_a_value)];
|
||||
}
|
||||
},
|
||||
getAllCodeActions(context: CodeFixAllContext) {
|
||||
return codeFixAll(context, errorCodes, (changes, diag) => makeChange(changes, diag.file, diag, context.program, new Set()));
|
||||
}
|
||||
});
|
||||
|
||||
function makeChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, span: TextSpan, program: Program, seen?: Set<ParameterDeclaration>) {
|
||||
const node = getTokenAtPosition(sourceFile, span.start);
|
||||
if (!isIdentifier(node) || !isCallExpression(node.parent) || node.parent.expression !== node || node.parent.arguments.length !== 0) return;
|
||||
|
||||
const checker = program.getTypeChecker();
|
||||
const symbol = checker.getSymbolAtLocation(node);
|
||||
|
||||
// decl should be `new Promise((<decl>) => {})`
|
||||
const decl = symbol?.valueDeclaration;
|
||||
if (!decl || !isParameter(decl) || !isNewExpression(decl.parent.parent)) return;
|
||||
|
||||
// no need to make this change if we have already seen this parameter.
|
||||
if (seen?.has(decl)) return;
|
||||
seen?.add(decl);
|
||||
|
||||
const typeArguments = getEffectiveTypeArguments(decl.parent.parent);
|
||||
if (some(typeArguments)) {
|
||||
// append ` | void` to type argument
|
||||
const typeArgument = typeArguments[0];
|
||||
const needsParens = !isUnionTypeNode(typeArgument) && !isParenthesizedTypeNode(typeArgument) &&
|
||||
isParenthesizedTypeNode(factory.createUnionTypeNode([typeArgument, factory.createKeywordTypeNode(SyntaxKind.VoidKeyword)]).types[0]);
|
||||
if (needsParens) {
|
||||
changes.insertText(sourceFile, typeArgument.pos, "(");
|
||||
}
|
||||
changes.insertText(sourceFile, typeArgument.end, needsParens ? ") | void" : " | void");
|
||||
}
|
||||
else {
|
||||
// make sure the Promise is type is untyped (i.e., `unknown`)
|
||||
const signature = checker.getResolvedSignature(node.parent);
|
||||
const parameter = signature?.parameters[0];
|
||||
const parameterType = parameter && checker.getTypeOfSymbolAtLocation(parameter, decl.parent.parent);
|
||||
if (isInJSFile(decl)) {
|
||||
if (!parameterType || parameterType.flags & TypeFlags.AnyOrUnknown) {
|
||||
// give the expression a type
|
||||
changes.insertText(sourceFile, decl.parent.parent.end, `)`);
|
||||
changes.insertText(sourceFile, skipTrivia(sourceFile.text, decl.parent.parent.pos), `/** @type {Promise<void>} */(`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!parameterType || parameterType.flags & TypeFlags.Unknown) {
|
||||
// add `void` type argument
|
||||
changes.insertText(sourceFile, decl.parent.parent.expression.end, "<void>");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getEffectiveTypeArguments(node: NewExpression) {
|
||||
if (isInJSFile(node)) {
|
||||
if (isParenthesizedExpression(node.parent)) {
|
||||
const jsDocType = getJSDocTypeTag(node.parent)?.typeExpression.type;
|
||||
if (jsDocType && isTypeReferenceNode(jsDocType) && isIdentifier(jsDocType.typeName) && idText(jsDocType.typeName) === "Promise") {
|
||||
return jsDocType.typeArguments;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return node.typeArguments;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -107,6 +107,7 @@
|
||||
"codefixes/splitTypeOnlyImport.ts",
|
||||
"codefixes/convertConstToLet.ts",
|
||||
"codefixes/fixExpectedComma.ts",
|
||||
"codefixes/fixAddVoidToPromise.ts",
|
||||
"refactors/convertExport.ts",
|
||||
"refactors/convertImport.ts",
|
||||
"refactors/convertToOptionalChainExpression.ts",
|
||||
|
||||
14
tests/cases/fourslash/codeFixAddVoidToPromise.1.ts
Normal file
14
tests/cases/fourslash/codeFixAddVoidToPromise.1.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @target: esnext
|
||||
// @lib: es2015
|
||||
// @strict: true
|
||||
|
||||
////const p1 = new Promise(resolve => resolve());
|
||||
|
||||
verify.codeFix({
|
||||
errorCode: 2794,
|
||||
description: "Add 'void' to Promise resolved without a value",
|
||||
index: 0,
|
||||
newFileContent: `const p1 = new Promise<void>(resolve => resolve());`
|
||||
});
|
||||
14
tests/cases/fourslash/codeFixAddVoidToPromise.2.ts
Normal file
14
tests/cases/fourslash/codeFixAddVoidToPromise.2.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @target: esnext
|
||||
// @lib: es2015
|
||||
// @strict: true
|
||||
|
||||
////const p2 = new Promise<number>(resolve => resolve());
|
||||
|
||||
verify.codeFix({
|
||||
errorCode: 2794,
|
||||
description: "Add 'void' to Promise resolved without a value",
|
||||
index: 0,
|
||||
newFileContent: `const p2 = new Promise<number | void>(resolve => resolve());`
|
||||
});
|
||||
14
tests/cases/fourslash/codeFixAddVoidToPromise.3.ts
Normal file
14
tests/cases/fourslash/codeFixAddVoidToPromise.3.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @target: esnext
|
||||
// @lib: es2015
|
||||
// @strict: true
|
||||
|
||||
////const p3 = new Promise<number | string>(resolve => resolve());
|
||||
|
||||
verify.codeFix({
|
||||
errorCode: 2794,
|
||||
description: "Add 'void' to Promise resolved without a value",
|
||||
index: 0,
|
||||
newFileContent: `const p3 = new Promise<number | string | void>(resolve => resolve());`
|
||||
});
|
||||
14
tests/cases/fourslash/codeFixAddVoidToPromise.4.ts
Normal file
14
tests/cases/fourslash/codeFixAddVoidToPromise.4.ts
Normal file
@ -0,0 +1,14 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @target: esnext
|
||||
// @lib: es2015
|
||||
// @strict: true
|
||||
|
||||
////const p4 = new Promise<{ x: number } & { y: string }>(resolve => resolve());
|
||||
|
||||
verify.codeFix({
|
||||
errorCode: 2794,
|
||||
description: "Add 'void' to Promise resolved without a value",
|
||||
index: 0,
|
||||
newFileContent: `const p4 = new Promise<({ x: number } & { y: string }) | void>(resolve => resolve());`
|
||||
});
|
||||
9
tests/cases/fourslash/codeFixAddVoidToPromise.5.ts
Normal file
9
tests/cases/fourslash/codeFixAddVoidToPromise.5.ts
Normal file
@ -0,0 +1,9 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @target: esnext
|
||||
// @lib: es2015
|
||||
// @strict: true
|
||||
|
||||
////const p4: Promise<number> = new Promise(resolve => resolve());
|
||||
|
||||
verify.not.codeFixAvailable();
|
||||
16
tests/cases/fourslash/codeFixAddVoidToPromiseJS.1.ts
Normal file
16
tests/cases/fourslash/codeFixAddVoidToPromiseJS.1.ts
Normal file
@ -0,0 +1,16 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @target: esnext
|
||||
// @lib: es2015
|
||||
// @strict: true
|
||||
// @allowJS: true
|
||||
// @checkJS: true
|
||||
// @filename: main.js
|
||||
////const p1 = new Promise(resolve => resolve());
|
||||
|
||||
verify.codeFix({
|
||||
errorCode: 2794,
|
||||
description: "Add 'void' to Promise resolved without a value",
|
||||
index: 2,
|
||||
newFileContent: `const p1 = /** @type {Promise<void>} */(new Promise(resolve => resolve()));`
|
||||
});
|
||||
16
tests/cases/fourslash/codeFixAddVoidToPromiseJS.2.ts
Normal file
16
tests/cases/fourslash/codeFixAddVoidToPromiseJS.2.ts
Normal file
@ -0,0 +1,16 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @target: esnext
|
||||
// @lib: es2015
|
||||
// @strict: true
|
||||
// @allowJS: true
|
||||
// @checkJS: true
|
||||
// @filename: main.js
|
||||
////const p2 = /** @type {Promise<number>} */(new Promise(resolve => resolve()));
|
||||
|
||||
verify.codeFix({
|
||||
errorCode: 2794,
|
||||
description: "Add 'void' to Promise resolved without a value",
|
||||
index: 2,
|
||||
newFileContent: `const p2 = /** @type {Promise<number | void>} */(new Promise(resolve => resolve()));`
|
||||
});
|
||||
16
tests/cases/fourslash/codeFixAddVoidToPromiseJS.3.ts
Normal file
16
tests/cases/fourslash/codeFixAddVoidToPromiseJS.3.ts
Normal file
@ -0,0 +1,16 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @target: esnext
|
||||
// @lib: es2015
|
||||
// @strict: true
|
||||
// @allowJS: true
|
||||
// @checkJS: true
|
||||
// @filename: main.js
|
||||
////const p3 = /** @type {Promise<number | string>} */(new Promise(resolve => resolve()));
|
||||
|
||||
verify.codeFix({
|
||||
errorCode: 2794,
|
||||
description: "Add 'void' to Promise resolved without a value",
|
||||
index: 2,
|
||||
newFileContent: `const p3 = /** @type {Promise<number | string | void>} */(new Promise(resolve => resolve()));`
|
||||
});
|
||||
16
tests/cases/fourslash/codeFixAddVoidToPromiseJS.4.ts
Normal file
16
tests/cases/fourslash/codeFixAddVoidToPromiseJS.4.ts
Normal file
@ -0,0 +1,16 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @target: esnext
|
||||
// @lib: es2015
|
||||
// @strict: true
|
||||
// @allowJS: true
|
||||
// @checkJS: true
|
||||
// @filename: main.js
|
||||
////const p4 = /** @type {Promise<{ x: number } & { y: string }>} */(new Promise(resolve => resolve()));
|
||||
|
||||
verify.codeFix({
|
||||
errorCode: 2794,
|
||||
description: "Add 'void' to Promise resolved without a value",
|
||||
index: 2,
|
||||
newFileContent: `const p4 = /** @type {Promise<({ x: number } & { y: string }) | void>} */(new Promise(resolve => resolve()));`
|
||||
});
|
||||
12
tests/cases/fourslash/codeFixAddVoidToPromiseJS.5.ts
Normal file
12
tests/cases/fourslash/codeFixAddVoidToPromiseJS.5.ts
Normal file
@ -0,0 +1,12 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @target: esnext
|
||||
// @lib: es2015
|
||||
// @strict: true
|
||||
// @allowJS: true
|
||||
// @checkJS: true
|
||||
// @filename: main.js
|
||||
/////** @type {Promise<number>} */
|
||||
////const p2 = new Promise(resolve => resolve());
|
||||
|
||||
verify.not.codeFixAvailable("Add 'void' to Promise resolved without a value");
|
||||
21
tests/cases/fourslash/codeFixAddVoidToPromiseJS_all.ts
Normal file
21
tests/cases/fourslash/codeFixAddVoidToPromiseJS_all.ts
Normal file
@ -0,0 +1,21 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @target: esnext
|
||||
// @lib: es2015
|
||||
// @strict: true
|
||||
// @allowJS: true
|
||||
// @checkJS: true
|
||||
// @filename: main.js
|
||||
////const p1 = new Promise(resolve => resolve());
|
||||
////const p2 = /** @type {Promise<number>} */(new Promise(resolve => resolve()));
|
||||
////const p3 = /** @type {Promise<number | string>} */(new Promise(resolve => resolve()));
|
||||
////const p4 = /** @type {Promise<{ x: number } & { y: string }>} */(new Promise(resolve => resolve()));
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "addVoidToPromise",
|
||||
fixAllDescription: ts.Diagnostics.Add_void_to_all_Promises_resolved_without_a_value.message,
|
||||
newFileContent: `const p1 = /** @type {Promise<void>} */(new Promise(resolve => resolve()));
|
||||
const p2 = /** @type {Promise<number | void>} */(new Promise(resolve => resolve()));
|
||||
const p3 = /** @type {Promise<number | string | void>} */(new Promise(resolve => resolve()));
|
||||
const p4 = /** @type {Promise<({ x: number } & { y: string }) | void>} */(new Promise(resolve => resolve()));`
|
||||
});
|
||||
19
tests/cases/fourslash/codeFixAddVoidToPromise_all.ts
Normal file
19
tests/cases/fourslash/codeFixAddVoidToPromise_all.ts
Normal file
@ -0,0 +1,19 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @target: esnext
|
||||
// @lib: es2015
|
||||
// @strict: true
|
||||
|
||||
////const p1 = new Promise(resolve => resolve());
|
||||
////const p2 = new Promise<number>(resolve => resolve());
|
||||
////const p3 = new Promise<number | string>(resolve => resolve());
|
||||
////const p4 = new Promise<{ x: number } & { y: string }>(resolve => resolve());
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "addVoidToPromise",
|
||||
fixAllDescription: ts.Diagnostics.Add_void_to_all_Promises_resolved_without_a_value.message,
|
||||
newFileContent: `const p1 = new Promise<void>(resolve => resolve());
|
||||
const p2 = new Promise<number | void>(resolve => resolve());
|
||||
const p3 = new Promise<number | string | void>(resolve => resolve());
|
||||
const p4 = new Promise<({ x: number } & { y: string }) | void>(resolve => resolve());`
|
||||
});
|
||||
@ -47,7 +47,7 @@ class C implements I<number> {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
[Symbol.match]: boolean;
|
||||
[Symbol.replace](...args: {}) {
|
||||
[Symbol.replace](...args: any[]) {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
[Symbol.search](str: string): number {
|
||||
@ -56,7 +56,7 @@ class C implements I<number> {
|
||||
[Symbol.species](): number {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
[Symbol.split](str: string, limit?: number): {} {
|
||||
[Symbol.split](str: string, limit?: number): string[] {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
[Symbol.toPrimitive](hint: "number"): number;
|
||||
@ -65,7 +65,7 @@ class C implements I<number> {
|
||||
[Symbol.toPrimitive](hint: any) {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
[Symbol.toStringTag]: string\;
|
||||
[Symbol.toStringTag]: string;
|
||||
[Symbol.unscopables]: any;
|
||||
}`,
|
||||
});
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
//// })
|
||||
//// /*1*/
|
||||
|
||||
verify.numberOfErrorsInCurrentFile(2);
|
||||
verify.numberOfErrorsInCurrentFile(1);
|
||||
goTo.marker("1");
|
||||
edit.insert(" ");
|
||||
verify.numberOfErrorsInCurrentFile(2);
|
||||
verify.numberOfErrorsInCurrentFile(1);
|
||||
@ -11,4 +11,4 @@
|
||||
verify.numberOfErrorsInCurrentFile(0);
|
||||
goTo.marker("1");
|
||||
edit.insert("(");
|
||||
verify.numberOfErrorsInCurrentFile(3);
|
||||
verify.numberOfErrorsInCurrentFile(1);
|
||||
Loading…
x
Reference in New Issue
Block a user