diff options
56 files changed, 314 insertions, 179 deletions
diff --git a/cli/compilers/ts.rs b/cli/compilers/ts.rs index dec74c256..0261b983e 100644 --- a/cli/compilers/ts.rs +++ b/cli/compilers/ts.rs @@ -714,7 +714,7 @@ mod tests { .unwrap() .code .as_bytes() - .starts_with(b"console.log(\"Hello World\");")); + .starts_with(b"\"use strict\";\nconsole.log(\"Hello World\");")); } #[tokio::test] diff --git a/cli/compilers/wasm_wrap.js b/cli/compilers/wasm_wrap.js index c90bd5540..98892b8e0 100644 --- a/cli/compilers/wasm_wrap.js +++ b/cli/compilers/wasm_wrap.js @@ -1,3 +1,4 @@ +// @ts-nocheck const importObject = Object.create(null); //IMPORTS diff --git a/cli/js/body_test.ts b/cli/js/body_test.ts index 2ac4d1314..d7f5c6d61 100644 --- a/cli/js/body_test.ts +++ b/cli/js/body_test.ts @@ -45,7 +45,7 @@ testPerm({ net: true }, async function bodyMultipartFormData(): Promise<void> { const formData = await body.formData(); assert(formData.has("field_1")); - assertEquals(formData.get("field_1").toString(), "value_1 \r\n"); + assertEquals(formData.get("field_1")!.toString(), "value_1 \r\n"); assert(formData.has("field_2")); }); @@ -62,7 +62,7 @@ testPerm({ net: true }, async function bodyURLEncodedFormData(): Promise<void> { const formData = await body.formData(); assert(formData.has("field_1")); - assertEquals(formData.get("field_1").toString(), "Hi"); + assertEquals(formData.get("field_1")!.toString(), "Hi"); assert(formData.has("field_2")); - assertEquals(formData.get("field_2").toString(), "<Deno>"); + assertEquals(formData.get("field_2")!.toString(), "<Deno>"); }); diff --git a/cli/js/buffer_test.ts b/cli/js/buffer_test.ts index 4b5701e54..72c0cab4b 100644 --- a/cli/js/buffer_test.ts +++ b/cli/js/buffer_test.ts @@ -3,7 +3,7 @@ // This code has been ported almost directly from Go's src/bytes/buffer_test.go // Copyright 2009 The Go Authors. All rights reserved. BSD license. // https://github.com/golang/go/blob/master/LICENSE -import { assertEquals, test } from "./test_util.ts"; +import { assert, assertEquals, test } from "./test_util.ts"; const { Buffer, readAll, readAllSync, writeAll, writeAllSync } = Deno; type Buffer = Deno.Buffer; @@ -78,12 +78,16 @@ function repeat(c: string, bytes: number): Uint8Array { test(function bufferNewBuffer(): void { init(); + assert(testBytes); + assert(testString); const buf = new Buffer(testBytes.buffer as ArrayBuffer); check(buf, testString); }); test(async function bufferBasicOperations(): Promise<void> { init(); + assert(testBytes); + assert(testString); const buf = new Buffer(); for (let i = 0; i < 5; i++) { check(buf, ""); @@ -134,8 +138,8 @@ test(async function bufferLargeByteWrites(): Promise<void> { const buf = new Buffer(); const limit = 9; for (let i = 3; i < limit; i += 3) { - const s = await fillBytes(buf, "", 5, testBytes); - await empty(buf, s, new Uint8Array(Math.floor(testString.length / i))); + const s = await fillBytes(buf, "", 5, testBytes!); + await empty(buf, s, new Uint8Array(Math.floor(testString!.length / i))); } check(buf, ""); }); @@ -161,6 +165,8 @@ test(async function bufferTooLargeByteWrites(): Promise<void> { test(async function bufferLargeByteReads(): Promise<void> { init(); + assert(testBytes); + assert(testString); const buf = new Buffer(); for (let i = 3; i < 30; i += 3) { const n = Math.floor(testBytes.byteLength / i); @@ -177,6 +183,8 @@ test(function bufferCapWithPreallocatedSlice(): void { test(async function bufferReadFrom(): Promise<void> { init(); + assert(testBytes); + assert(testString); const buf = new Buffer(); for (let i = 3; i < 30; i += 3) { const s = await fillBytes( @@ -194,6 +202,8 @@ test(async function bufferReadFrom(): Promise<void> { test(async function bufferReadFromSync(): Promise<void> { init(); + assert(testBytes); + assert(testString); const buf = new Buffer(); for (let i = 3; i < 30; i += 3) { const s = await fillBytes( @@ -236,6 +246,7 @@ test(async function bufferTestGrow(): Promise<void> { test(async function testReadAll(): Promise<void> { init(); + assert(testBytes); const reader = new Buffer(testBytes.buffer as ArrayBuffer); const actualBytes = await readAll(reader); assertEquals(testBytes.byteLength, actualBytes.byteLength); @@ -246,6 +257,7 @@ test(async function testReadAll(): Promise<void> { test(function testReadAllSync(): void { init(); + assert(testBytes); const reader = new Buffer(testBytes.buffer as ArrayBuffer); const actualBytes = readAllSync(reader); assertEquals(testBytes.byteLength, actualBytes.byteLength); @@ -256,6 +268,7 @@ test(function testReadAllSync(): void { test(async function testWriteAll(): Promise<void> { init(); + assert(testBytes); const writer = new Buffer(); await writeAll(writer, testBytes); const actualBytes = writer.bytes(); @@ -267,6 +280,7 @@ test(async function testWriteAll(): Promise<void> { test(function testWriteAllSync(): void { init(); + assert(testBytes); const writer = new Buffer(); writeAllSync(writer, testBytes); const actualBytes = writer.bytes(); diff --git a/cli/js/chmod_test.ts b/cli/js/chmod_test.ts index 3ecb4256a..b3b0a2ae2 100644 --- a/cli/js/chmod_test.ts +++ b/cli/js/chmod_test.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { testPerm, assertEquals } from "./test_util.ts"; +import { testPerm, assert, assertEquals } from "./test_util.ts"; const isNotWindows = Deno.build.os !== "win"; @@ -16,6 +16,7 @@ testPerm({ read: true, write: true }, function chmodSyncSuccess(): void { // Check success when not on windows if (isNotWindows) { const fileInfo = Deno.statSync(filename); + assert(fileInfo.mode); assertEquals(fileInfo.mode & 0o777, 0o777); } }); @@ -35,14 +36,17 @@ if (isNotWindows) { Deno.symlinkSync(filename, symlinkName); let symlinkInfo = Deno.lstatSync(symlinkName); + assert(symlinkInfo.mode); const symlinkMode = symlinkInfo.mode & 0o777; // platform dependent Deno.chmodSync(symlinkName, 0o777); // Change actual file mode, not symlink const fileInfo = Deno.statSync(filename); + assert(fileInfo.mode); assertEquals(fileInfo.mode & 0o777, 0o777); symlinkInfo = Deno.lstatSync(symlinkName); + assert(symlinkInfo.mode); assertEquals(symlinkInfo.mode & 0o777, symlinkMode); } ); @@ -86,6 +90,7 @@ testPerm({ read: true, write: true }, async function chmodSuccess(): Promise< // Check success when not on windows if (isNotWindows) { const fileInfo = Deno.statSync(filename); + assert(fileInfo.mode); assertEquals(fileInfo.mode & 0o777, 0o777); } }); @@ -105,14 +110,17 @@ if (isNotWindows) { Deno.symlinkSync(filename, symlinkName); let symlinkInfo = Deno.lstatSync(symlinkName); + assert(symlinkInfo.mode); const symlinkMode = symlinkInfo.mode & 0o777; // platform dependent await Deno.chmod(symlinkName, 0o777); // Just change actual file mode, not symlink const fileInfo = Deno.statSync(filename); + assert(fileInfo.mode); assertEquals(fileInfo.mode & 0o777, 0o777); symlinkInfo = Deno.lstatSync(symlinkName); + assert(symlinkInfo.mode); assertEquals(symlinkInfo.mode & 0o777, symlinkMode); } ); diff --git a/cli/js/compiler_host.ts b/cli/js/compiler_host.ts index 8f19eb326..d44bc7a03 100644 --- a/cli/js/compiler_host.ts +++ b/cli/js/compiler_host.ts @@ -49,8 +49,7 @@ export const defaultBundlerOptions: ts.CompilerOptions = { export const defaultCompileOptions: ts.CompilerOptions = { allowJs: true, allowNonTsExtensions: true, - // TODO(#3324) Enable strict mode for user code. - // strict: true, + strict: true, checkJs: false, esModuleInterop: true, module: ts.ModuleKind.ESNext, diff --git a/cli/js/console_test.ts b/cli/js/console_test.ts index b80dd8284..d9492cf2d 100644 --- a/cli/js/console_test.ts +++ b/cli/js/console_test.ts @@ -14,8 +14,8 @@ const customInspect = Deno.symbols.customInspect; const { Console, stringifyArgs - // eslint-disable-next-line @typescript-eslint/no-explicit-any -} = Deno[Deno.symbols.internal] as any; + // @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol +} = Deno[Deno.symbols.internal]; function stringify(...args: unknown[]): string { return stringifyArgs(args).replace(/\n$/, ""); @@ -306,6 +306,7 @@ test(function consoleTestCallToStringOnLabel(): void { for (const method of methods) { let hasCalled = false; + // @ts-ignore console[method]({ toString(): void { hasCalled = true; @@ -451,6 +452,7 @@ test(function consoleGroup(): void { // console.group with console.warn test test(function consoleGroupWarn(): void { mockConsole((console, _out, _err, both): void => { + assert(both); console.warn("1"); console.group(); console.warn("2"); @@ -694,6 +696,7 @@ test(function consoleDirXml(): void { test(function consoleTrace(): void { mockConsole((console, _out, err): void => { console.trace("%s", "custom message"); + assert(err); assert(err.toString().includes("Trace: custom message")); }); }); diff --git a/cli/js/error_stack_test.ts b/cli/js/error_stack_test.ts index e4e44c77f..12755c166 100644 --- a/cli/js/error_stack_test.ts +++ b/cli/js/error_stack_test.ts @@ -1,8 +1,8 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { test, assert } from "./test_util.ts"; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const { setPrepareStackTrace } = Deno[Deno.symbols.internal] as any; +// @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol +const { setPrepareStackTrace } = Deno[Deno.symbols.internal]; interface CallSite { getThis(): unknown; diff --git a/cli/js/event_target_test.ts b/cli/js/event_target_test.ts index aead97ed3..34d42d014 100644 --- a/cli/js/event_target_test.ts +++ b/cli/js/event_target_test.ts @@ -4,8 +4,11 @@ import { test, assertEquals } from "./test_util.ts"; test(function addEventListenerTest(): void { const document = new EventTarget(); + // @ts-ignore tests ignoring the type system for resilience assertEquals(document.addEventListener("x", null, false), undefined); + // @ts-ignore assertEquals(document.addEventListener("x", null, true), undefined); + // @ts-ignore assertEquals(document.addEventListener("x", null), undefined); }); @@ -14,7 +17,7 @@ test(function constructedEventTargetCanBeUsedAsExpected(): void { const event = new Event("foo", { bubbles: true, cancelable: false }); let callCount = 0; - const listener = (e): void => { + const listener = (e: Event): void => { assertEquals(e, event); ++callCount; }; @@ -34,11 +37,19 @@ test(function constructedEventTargetCanBeUsedAsExpected(): void { test(function anEventTargetCanBeSubclassed(): void { class NicerEventTarget extends EventTarget { - on(type, callback?, options?): void { + on( + type: string, + callback: (e: Event) => void | null, + options?: __domTypes.AddEventListenerOptions + ): void { this.addEventListener(type, callback, options); } - off(type, callback?, options?): void { + off( + type: string, + callback: (e: Event) => void | null, + options?: __domTypes.EventListenerOptions + ): void { this.removeEventListener(type, callback, options); } } @@ -60,8 +71,11 @@ test(function anEventTargetCanBeSubclassed(): void { test(function removingNullEventListenerShouldSucceed(): void { const document = new EventTarget(); + // @ts-ignore assertEquals(document.removeEventListener("x", null, false), undefined); + // @ts-ignore assertEquals(document.removeEventListener("x", null, true), undefined); + // @ts-ignore assertEquals(document.removeEventListener("x", null), undefined); }); @@ -70,7 +84,7 @@ test(function constructedEventTargetUseObjectPrototype(): void { const event = new Event("toString", { bubbles: true, cancelable: false }); let callCount = 0; - const listener = (e): void => { + const listener = (e: Event): void => { assertEquals(e, event); ++callCount; }; diff --git a/cli/js/event_test.ts b/cli/js/event_test.ts index affd979ee..2ff23daf9 100644 --- a/cli/js/event_test.ts +++ b/cli/js/event_test.ts @@ -1,5 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { test, assertEquals, assertNotEquals } from "./test_util.ts"; +import { test, assertEquals, assert } from "./test_util.ts"; test(function eventInitializedWithType(): void { const type = "click"; @@ -70,7 +70,8 @@ test(function eventPreventDefaultSuccess(): void { }); test(function eventInitializedWithNonStringType(): void { - const type = undefined; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const type: any = undefined; const event = new Event(type); assertEquals(event.isTrusted, false); @@ -84,12 +85,12 @@ test(function eventInitializedWithNonStringType(): void { // ref https://github.com/web-platform-tests/wpt/blob/master/dom/events/Event-isTrusted.any.js test(function eventIsTrusted(): void { const desc1 = Object.getOwnPropertyDescriptor(new Event("x"), "isTrusted"); - assertNotEquals(desc1, undefined); + assert(desc1); assertEquals(typeof desc1.get, "function"); const desc2 = Object.getOwnPropertyDescriptor(new Event("x"), "isTrusted"); - assertNotEquals(desc2, undefined); - assertEquals(typeof desc2.get, "function"); + assert(desc2); + assertEquals(typeof desc2!.get, "function"); - assertEquals(desc1.get, desc2.get); + assertEquals(desc1!.get, desc2!.get); }); diff --git a/cli/js/fetch_test.ts b/cli/js/fetch_test.ts index 2b3d03a38..c63d05501 100644 --- a/cli/js/fetch_test.ts +++ b/cli/js/fetch_test.ts @@ -54,7 +54,7 @@ testPerm({ net: true }, async function fetchHeaders(): Promise<void> { const response = await fetch("http://localhost:4545/cli/tests/fixture.json"); const headers = response.headers; assertEquals(headers.get("Content-Type"), "application/json"); - assert(headers.get("Server").startsWith("SimpleHTTP")); + assert(headers.get("Server")!.startsWith("SimpleHTTP")); }); testPerm({ net: true }, async function fetchBlob(): Promise<void> { @@ -93,10 +93,10 @@ testPerm({ net: true }, async function responseClone(): Promise<void> { assert(response !== response1); assertEquals(response.status, response1.status); assertEquals(response.statusText, response1.statusText); - const ab = await response.arrayBuffer(); - const ab1 = await response1.arrayBuffer(); - for (let i = 0; i < ab.byteLength; i++) { - assertEquals(ab[i], ab1[i]); + const u8a = new Uint8Array(await response.arrayBuffer()); + const u8a1 = new Uint8Array(await response1.arrayBuffer()); + for (let i = 0; i < u8a.byteLength; i++) { + assertEquals(u8a[i], u8a1[i]); } }); @@ -119,7 +119,7 @@ testPerm({ net: true }, async function fetchMultipartFormDataSuccess(): Promise< ); const formData = await response.formData(); assert(formData.has("field_1")); - assertEquals(formData.get("field_1").toString(), "value_1 \r\n"); + assertEquals(formData.get("field_1")!.toString(), "value_1 \r\n"); assert(formData.has("field_2")); /* TODO(ry) Re-enable this test once we bring back the global File type. const file = formData.get("field_2") as File; @@ -136,9 +136,9 @@ testPerm( ); const formData = await response.formData(); assert(formData.has("field_1")); - assertEquals(formData.get("field_1").toString(), "Hi"); + assertEquals(formData.get("field_1")!.toString(), "Hi"); assert(formData.has("field_2")); - assertEquals(formData.get("field_2").toString(), "<Deno>"); + assertEquals(formData.get("field_2")!.toString(), "<Deno>"); } ); @@ -179,7 +179,7 @@ testPerm({ net: true }, async function fetchInitStringBody(): Promise<void> { }); const text = await response.text(); assertEquals(text, data); - assert(response.headers.get("content-type").startsWith("text/plain")); + assert(response.headers.get("content-type")!.startsWith("text/plain")); }); testPerm({ net: true }, async function fetchRequestInitStringBody(): Promise< @@ -220,7 +220,7 @@ testPerm({ net: true }, async function fetchInitURLSearchParamsBody(): Promise< assertEquals(text, data); assert( response.headers - .get("content-type") + .get("content-type")! .startsWith("application/x-www-form-urlencoded") ); }); @@ -236,7 +236,7 @@ testPerm({ net: true }, async function fetchInitBlobBody(): Promise<void> { }); const text = await response.text(); assertEquals(text, data); - assert(response.headers.get("content-type").startsWith("text/javascript")); + assert(response.headers.get("content-type")!.startsWith("text/javascript")); }); testPerm({ net: true }, async function fetchUserAgent(): Promise<void> { diff --git a/cli/js/file_test.ts b/cli/js/file_test.ts index 2d009c0c2..8fc37f701 100644 --- a/cli/js/file_test.ts +++ b/cli/js/file_test.ts @@ -1,7 +1,8 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { test, assert, assertEquals } from "./test_util.ts"; -function testFirstArgument(arg1, expectedSize): void { +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function testFirstArgument(arg1: any[], expectedSize: number): void { const file = new File(arg1, "name"); assert(file instanceof File); assertEquals(file.name, "name"); @@ -76,7 +77,8 @@ test(function fileObjectInFileBits(): void { testFirstArgument([{}], 15); }); -function testSecondArgument(arg2, expectedFileName): void { +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function testSecondArgument(arg2: any, expectedFileName: string): void { const file = new File(["bits"], arg2); assert(file instanceof File); assertEquals(file.name, expectedFileName); diff --git a/cli/js/files_test.ts b/cli/js/files_test.ts index 8f4beb085..03e4d00e9 100644 --- a/cli/js/files_test.ts +++ b/cli/js/files_test.ts @@ -157,6 +157,7 @@ testPerm({ write: true }, async function writeNullBufferFailure(): Promise< // writing null should throw an error let err; try { + // @ts-ignore await file.write(null); } catch (e) { err = e; @@ -182,6 +183,7 @@ testPerm( // reading file into null buffer should throw an error let err; try { + // @ts-ignore await file.read(null); } catch (e) { err = e; diff --git a/cli/js/form_data_test.ts b/cli/js/form_data_test.ts index a40326fba..10147d8b9 100644 --- a/cli/js/form_data_test.ts +++ b/cli/js/form_data_test.ts @@ -36,7 +36,9 @@ test(function formDataParamsGetSuccess(): void { formData.append("a", "true"); formData.append("b", "false"); formData.append("a", "null"); + // @ts-ignore formData.append("d", undefined); + // @ts-ignore formData.append("e", null); assertEquals(formData.get("a"), "true"); assertEquals(formData.get("b"), "false"); @@ -63,8 +65,10 @@ test(function formDataParamsSetSuccess(): void { assertEquals(formData.getAll("b"), ["false"]); formData.set("a", "false"); assertEquals(formData.getAll("a"), ["false"]); + // @ts-ignore formData.set("d", undefined); assertEquals(formData.get("d"), "undefined"); + // @ts-ignore formData.set("e", null); assertEquals(formData.get("e"), "null"); }); @@ -101,15 +105,22 @@ test(function formDataParamsForEachSuccess(): void { }); test(function formDataParamsArgumentsCheck(): void { - const methodRequireOneParam = ["delete", "getAll", "get", "has", "forEach"]; + const methodRequireOneParam = [ + "delete", + "getAll", + "get", + "has", + "forEach" + ] as const; - const methodRequireTwoParams = ["append", "set"]; + const methodRequireTwoParams = ["append", "set"] as const; methodRequireOneParam.forEach((method): void => { const formData = new FormData(); let hasThrown = 0; let errMsg = ""; try { + // @ts-ignore formData[method](); hasThrown = 1; } catch (err) { @@ -133,6 +144,7 @@ test(function formDataParamsArgumentsCheck(): void { let errMsg = ""; try { + // @ts-ignore formData[method](); hasThrown = 1; } catch (err) { @@ -152,6 +164,7 @@ test(function formDataParamsArgumentsCheck(): void { hasThrown = 0; errMsg = ""; try { + // @ts-ignore formData[method]("foo"); hasThrown = 1; } catch (err) { diff --git a/cli/js/headers_test.ts b/cli/js/headers_test.ts index 15e1191f5..65e04ada3 100644 --- a/cli/js/headers_test.ts +++ b/cli/js/headers_test.ts @@ -2,8 +2,8 @@ import { test, assert, assertEquals } from "./test_util.ts"; const { stringifyArgs - // eslint-disable-next-line @typescript-eslint/no-explicit-any -} = Deno[Deno.symbols.internal] as any; + // @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol +} = Deno[Deno.symbols.internal]; // Logic heavily copied from web-platform-tests, make // sure pass mostly header basic test @@ -13,6 +13,7 @@ test(function newHeaderTest(): void { new Headers(undefined); new Headers({}); try { + // @ts-ignore new Headers(null); } catch (e) { assertEquals( @@ -22,14 +23,16 @@ test(function newHeaderTest(): void { } }); -const headerDict = { +const headerDict: Record<string, string> = { name1: "value1", name2: "value2", name3: "value3", + // @ts-ignore name4: undefined, "Content-Type": "value4" }; -const headerSeq = []; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const headerSeq: any[] = []; for (const name in headerDict) { headerSeq.push([name, headerDict[name]]); } @@ -133,7 +136,7 @@ test(function headerValuesSuccess(): void { } }); -const headerEntriesDict = { +const headerEntriesDict: Record<string, string> = { name1: "value1", Name2: "value2", name: "value3", @@ -261,6 +264,7 @@ test(function headerParamsArgumentsCheck(): void { let hasThrown = 0; let errMsg = ""; try { + // @ts-ignore headers[method](); hasThrown = 1; } catch (err) { @@ -284,6 +288,7 @@ test(function headerParamsArgumentsCheck(): void { let errMsg = ""; try { + // @ts-ignore headers[method](); hasThrown = 1; } catch (err) { @@ -303,6 +308,7 @@ test(function headerParamsArgumentsCheck(): void { hasThrown = 0; errMsg = ""; try { + // @ts-ignore headers[method]("foo"); hasThrown = 1; } catch (err) { diff --git a/cli/js/internals_test.ts b/cli/js/internals_test.ts index 055995fdf..47aea09e7 100644 --- a/cli/js/internals_test.ts +++ b/cli/js/internals_test.ts @@ -4,7 +4,7 @@ import { test, assert } from "./test_util.ts"; test(function internalsExists(): void { const { stringifyArgs - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } = Deno[Deno.symbols.internal] as any; + // @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol + } = Deno[Deno.symbols.internal]; assert(!!stringifyArgs); }); diff --git a/cli/js/mixins/dom_iterable_test.ts b/cli/js/mixins/dom_iterable_test.ts index 466375d64..5dc45dc20 100644 --- a/cli/js/mixins/dom_iterable_test.ts +++ b/cli/js/mixins/dom_iterable_test.ts @@ -20,11 +20,8 @@ function setup() { Base, // This is using an internal API we don't want published as types, so having // to cast to any to "trick" TypeScript - // eslint-disable-next-line @typescript-eslint/no-explicit-any - DomIterable: (Deno[Deno.symbols.internal] as any).DomIterableMixin( - Base, - dataSymbol - ) + // @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol + DomIterable: Deno[Deno.symbols.internal].DomIterableMixin(Base, dataSymbol) }; } @@ -52,7 +49,12 @@ test(function testDomIterable(): void { result = []; const scope = {}; - function callback(value, key, parent): void { + function callback( + this: typeof scope, + value: number, + key: string, + parent: typeof domIterable + ): void { assertEquals(parent, domIterable); assert(key != null); assert(value != null); @@ -72,7 +74,7 @@ test(function testDomIterableScope(): void { // eslint-disable-next-line @typescript-eslint/no-explicit-any function checkScope(thisArg: any, expected: any): void { - function callback(): void { + function callback(this: typeof thisArg): void { assertEquals(this, expected); } domIterable.forEach(callback, thisArg); diff --git a/cli/js/net_test.ts b/cli/js/net_test.ts index e4d0be81f..68b1918b9 100644 --- a/cli/js/net_test.ts +++ b/cli/js/net_test.ts @@ -27,7 +27,7 @@ testPerm({ net: true }, async function netCloseWhileAccept(): Promise<void> { testPerm({ net: true }, async function netConcurrentAccept(): Promise<void> { const listener = Deno.listen({ port: 4502 }); let acceptErrCount = 0; - const checkErr = (e): void => { + const checkErr = (e: Deno.DenoError<Deno.ErrorKind>): void => { assertEquals(e.kind, Deno.ErrorKind.Other); if (e.message === "Listener has been closed") { assertEquals(acceptErrCount, 1); diff --git a/cli/js/os_test.ts b/cli/js/os_test.ts index 6d9309000..a461ba63e 100644 --- a/cli/js/os_test.ts +++ b/cli/js/os_test.ts @@ -56,7 +56,10 @@ if (Deno.build.os === "win") { // specified in `inputEnv`. The subprocess reads the environment variables // which are in the keys of `expectedEnv` and writes them to stdout as JSON. // It is then verified that these match with the values of `expectedEnv`. - const checkChildEnv = async (inputEnv, expectedEnv): Promise<void> => { + const checkChildEnv = async ( + inputEnv: Record<string, string>, + expectedEnv: Record<string, string> + ): Promise<void> => { const src = ` console.log( ${JSON.stringify(Object.keys(expectedEnv))}.map(k => Deno.env(k)) @@ -249,6 +252,7 @@ testPerm({ env: true }, function getDir(): void { if (Deno.build.os !== r.os) continue; if (r.shouldHaveValue) { const d = Deno.dir(s.kind); + assert(d); assert(d.length > 0); } } diff --git a/cli/js/process_test.ts b/cli/js/process_test.ts index 943359e54..dce4d9918 100644 --- a/cli/js/process_test.ts +++ b/cli/js/process_test.ts @@ -130,6 +130,7 @@ testPerm({ run: true }, async function runStdinPiped(): Promise<void> { args: ["python", "-c", "import sys; assert 'hello' == sys.stdin.read();"], stdin: "piped" }); + assert(p.stdin); assert(!p.stdout); assert(!p.stderr); @@ -137,7 +138,7 @@ testPerm({ run: true }, async function runStdinPiped(): Promise<void> { const n = await p.stdin.write(msg); assertEquals(n, msg.byteLength); - p.stdin.close(); + p.stdin!.close(); const status = await p.status(); assertEquals(status.success, true); @@ -155,16 +156,16 @@ testPerm({ run: true }, async function runStdoutPiped(): Promise<void> { assert(!p.stderr); const data = new Uint8Array(10); - let r = await p.stdout.read(data); + let r = await p.stdout!.read(data); if (r === Deno.EOF) { throw new Error("p.stdout.read(...) should not be EOF"); } assertEquals(r, 5); const s = new TextDecoder().decode(data.subarray(0, r)); assertEquals(s, "hello"); - r = await p.stdout.read(data); + r = await p.stdout!.read(data); assertEquals(r, Deno.EOF); - p.stdout.close(); + p.stdout!.close(); const status = await p.status(); assertEquals(status.success, true); @@ -182,16 +183,16 @@ testPerm({ run: true }, async function runStderrPiped(): Promise<void> { assert(!p.stdout); const data = new Uint8Array(10); - let r = await p.stderr.read(data); + let r = await p.stderr!.read(data); if (r === Deno.EOF) { throw new Error("p.stderr.read should not return EOF here"); } assertEquals(r, 5); const s = new TextDecoder().decode(data.subarray(0, r)); assertEquals(s, "hello"); - r = await p.stderr.read(data); + r = await p.stderr!.read(data); assertEquals(r, Deno.EOF); - p.stderr.close(); + p.stderr!.close(); const status = await p.status(); assertEquals(status.success, true); @@ -307,7 +308,7 @@ testPerm({ run: true }, async function runClose(): Promise<void> { p.close(); const data = new Uint8Array(10); - const r = await p.stderr.read(data); + const r = await p.stderr!.read(data); assertEquals(r, Deno.EOF); }); diff --git a/cli/js/resources_test.ts b/cli/js/resources_test.ts index 367b66217..5d1e27af7 100644 --- a/cli/js/resources_test.ts +++ b/cli/js/resources_test.ts @@ -39,8 +39,8 @@ testPerm({ read: true }, async function resourcesFile(): Promise<void> { Object.keys(resourcesAfter).length, Object.keys(resourcesBefore).length + 1 ); - const newRid = Object.keys(resourcesAfter).find((rid): boolean => { + const newRid = +Object.keys(resourcesAfter).find((rid): boolean => { return !resourcesBefore.hasOwnProperty(rid); - }); + })!; assertEquals(resourcesAfter[newRid], "fsFile"); }); diff --git a/cli/js/signal_test.ts b/cli/js/signal_test.ts index 06457314c..1c8658477 100644 --- a/cli/js/signal_test.ts +++ b/cli/js/signal_test.ts @@ -8,7 +8,7 @@ import { } from "./test_util.ts"; function defer(n: number): Promise<void> { - return new Promise((resolve, _) => { + return new Promise((resolve: () => void, _) => { setTimeout(resolve, n); }); } diff --git a/cli/js/stat_test.ts b/cli/js/stat_test.ts index 9b03c0ece..bce5449ac 100644 --- a/cli/js/stat_test.ts +++ b/cli/js/stat_test.ts @@ -210,7 +210,7 @@ if (isWindows) { const s = Deno.statSync(filename); assert(s.dev !== null); assert(s.ino !== null); - assertEquals(s.mode & 0o666, 0o666); + assertEquals(s.mode! & 0o666, 0o666); assertEquals(s.nlink, 2); assert(s.uid !== null); assert(s.gid !== null); diff --git a/cli/js/test_util.ts b/cli/js/test_util.ts index dbb7bf2c4..3e089486b 100644 --- a/cli/js/test_util.ts +++ b/cli/js/test_util.ts @@ -62,7 +62,10 @@ function permissionsMatch( requiredPerms: Permissions ): boolean { for (const permName in processPerms) { - if (processPerms[permName] !== requiredPerms[permName]) { + if ( + processPerms[permName as keyof Permissions] !== + requiredPerms[permName as keyof Permissions] + ) { return false; } } @@ -302,7 +305,7 @@ testPerm( async function assertAllUnitTestFilesImported(): Promise<void> { const directoryTestFiles = Deno.readDirSync("./cli/js") .map(k => k.name) - .filter(file => file.endsWith("_test.ts")); + .filter(file => file!.endsWith("_test.ts")); const unitTestsFile: Uint8Array = Deno.readFileSync( "./cli/js/unit_tests.ts" ); @@ -311,11 +314,11 @@ testPerm( .split("\n") .filter(line => line.startsWith("import") && line.includes("_test.ts")); const importedTestFiles = importLines.map( - relativeFilePath => relativeFilePath.match(/\/([^\/]+)";/)[1] + relativeFilePath => relativeFilePath.match(/\/([^\/]+)";/)![1] ); directoryTestFiles.forEach(dirFile => { - if (!importedTestFiles.includes(dirFile)) { + if (!importedTestFiles.includes(dirFile!)) { throw new Error( "cil/js/unit_tests.ts is missing import of test file: cli/js/" + dirFile diff --git a/cli/js/timers_test.ts b/cli/js/timers_test.ts index b71df9254..84811ff11 100644 --- a/cli/js/timers_test.ts +++ b/cli/js/timers_test.ts @@ -7,21 +7,22 @@ function deferred(): { // eslint-disable-next-line @typescript-eslint/no-explicit-any reject: (reason?: any) => void; } { - let resolve; - let reject; - const promise = new Promise((res, rej): void => { + let resolve: (value?: {} | PromiseLike<{}>) => void; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let reject: ((reason?: any) => void) | undefined = undefined; + const promise = new Promise<{}>((res, rej): void => { resolve = res; reject = rej; }); return { promise, - resolve, - reject + resolve: resolve!, + reject: reject! }; } -async function waitForMs(ms): Promise<number> { - return new Promise((resolve): number => setTimeout(resolve, ms)); +async function waitForMs(ms: number): Promise<number> { + return new Promise((resolve: () => void): number => setTimeout(resolve, ms)); } test(async function timeoutSuccess(): Promise<void> { @@ -133,7 +134,7 @@ test(async function intervalCancelSuccess(): Promise<void> { }); test(async function intervalOrdering(): Promise<void> { - const timers = []; + const timers: number[] = []; let timeouts = 0; function onTimeout(): void { ++timeouts; diff --git a/cli/js/tls_test.ts b/cli/js/tls_test.ts index 1273da34f..ac59a2eb9 100644 --- a/cli/js/tls_test.ts +++ b/cli/js/tls_test.ts @@ -195,7 +195,7 @@ testPerm({ read: true, net: true }, async function dialAndListenTLS(): Promise< assertEquals(ok, "OK"); const headers = await tpr.readMIMEHeader(); assert(headers !== Deno.EOF); - const contentLength = parseInt(headers.get("content-length")); + const contentLength = parseInt(headers.get("content-length")!); const bodyBuf = new Uint8Array(contentLength); await r.readFull(bodyBuf); assertEquals(decoder.decode(bodyBuf), "Hello World\n"); diff --git a/cli/js/url_search_params_test.ts b/cli/js/url_search_params_test.ts index c1343e59b..8619568bd 100644 --- a/cli/js/url_search_params_test.ts +++ b/cli/js/url_search_params_test.ts @@ -177,6 +177,7 @@ test(function urlSearchParamsAppendArgumentsCheck(): void { const searchParams = new URLSearchParams(); let hasThrown = 0; try { + // @ts-ignore searchParams[method](); hasThrown = 1; } catch (err) { @@ -193,6 +194,7 @@ test(function urlSearchParamsAppendArgumentsCheck(): void { const searchParams = new URLSearchParams(); let hasThrown = 0; try { + // @ts-ignore searchParams[method]("foo"); hasThrown = 1; } catch (err) { @@ -232,6 +234,7 @@ test(function urlSearchParamsCustomSymbolIterator(): void { test(function urlSearchParamsCustomSymbolIteratorWithNonStringParams(): void { const params = {}; + // @ts-ignore params[Symbol.iterator] = function*(): IterableIterator<[number, number]> { yield [1, 2]; }; diff --git a/cli/js/utime_test.ts b/cli/js/utime_test.ts index 15c218df4..72a4a6477 100644 --- a/cli/js/utime_test.ts +++ b/cli/js/utime_test.ts @@ -3,7 +3,9 @@ import { testPerm, assert, assertEquals } from "./test_util.ts"; // Allow 10 second difference. // Note this might not be enough for FAT (but we are not testing on such fs). -function assertFuzzyTimestampEquals(t1: number, t2: number): void { +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function assertFuzzyTimestampEquals(t1: any, t2: number): void { + assert(typeof t1 === "number"); assert(Math.abs(t1 - t2) < 10); } diff --git a/cli/js/write_file_test.ts b/cli/js/write_file_test.ts index 30500b594..2b952655f 100644 --- a/cli/js/write_file_test.ts +++ b/cli/js/write_file_test.ts @@ -50,9 +50,9 @@ testPerm({ read: true, write: true }, function writeFileSyncUpdatePerm(): void { const data = enc.encode("Hello"); const filename = Deno.makeTempDirSync() + "/test.txt"; Deno.writeFileSync(filename, data, { perm: 0o755 }); - assertEquals(Deno.statSync(filename).mode & 0o777, 0o755); + assertEquals(Deno.statSync(filename).mode! & 0o777, 0o755); Deno.writeFileSync(filename, data, { perm: 0o666 }); - assertEquals(Deno.statSync(filename).mode & 0o777, 0o666); + assertEquals(Deno.statSync(filename).mode! & 0o777, 0o666); } }); @@ -161,9 +161,9 @@ testPerm( const data = enc.encode("Hello"); const filename = Deno.makeTempDirSync() + "/test.txt"; await Deno.writeFile(filename, data, { perm: 0o755 }); - assertEquals(Deno.statSync(filename).mode & 0o777, 0o755); + assertEquals(Deno.statSync(filename).mode! & 0o777, 0o755); await Deno.writeFile(filename, data, { perm: 0o666 }); - assertEquals(Deno.statSync(filename).mode & 0o777, 0o666); + assertEquals(Deno.statSync(filename).mode! & 0o777, 0o666); } } ); diff --git a/cli/tests/046_jsx_test.tsx b/cli/tests/046_jsx_test.tsx index 4e9380eb8..a3df2aad7 100644 --- a/cli/tests/046_jsx_test.tsx +++ b/cli/tests/046_jsx_test.tsx @@ -1,3 +1,8 @@ +declare namespace JSX { + interface IntrinsicElements { + [elemName: string]: any; + } +} const React = { createElement(factory: any, props: any, ...children: any[]) { return {factory, props, children} diff --git a/cli/tests/048_media_types_jsx.ts b/cli/tests/048_media_types_jsx.ts index c2340de35..f6a498fdf 100644 --- a/cli/tests/048_media_types_jsx.ts +++ b/cli/tests/048_media_types_jsx.ts @@ -10,6 +10,16 @@ import { loaded as loadedJsx2 } from "http://localhost:4545/cli/tests/subdir/mt_ import { loaded as loadedJsx3 } from "http://localhost:4545/cli/tests/subdir/mt_text_ecmascript_jsx.j3.jsx"; import { loaded as loadedJsx4 } from "http://localhost:4545/cli/tests/subdir/mt_application_x_javascript_jsx.j4.jsx"; +declare global { + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace JSX { + interface IntrinsicElements { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + [elemName: string]: any; + } + } +} + console.log( "success", loadedTsx1, diff --git a/std/encoding/base32_test.ts b/std/encoding/base32_test.ts index eb51e44ab..28550d57a 100644 --- a/std/encoding/base32_test.ts +++ b/std/encoding/base32_test.ts @@ -6,7 +6,7 @@ import { encode, decode } from "./base32.ts"; // Lifted from https://stackoverflow.com/questions/38987784 const fromHexString = (hexString: string): Uint8Array => - new Uint8Array(hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16))); + new Uint8Array(hexString.match(/.{1,2}/g)!.map(byte => parseInt(byte, 16))); const toHexString = (bytes: Uint8Array): string => bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, "0"), ""); diff --git a/std/encoding/csv.ts b/std/encoding/csv.ts index 1314afcaa..12336b10d 100644 --- a/std/encoding/csv.ts +++ b/std/encoding/csv.ts @@ -46,7 +46,7 @@ function chkOptions(opt: ReadOptions): void { } if ( INVALID_RUNE.includes(opt.comma) || - INVALID_RUNE.includes(opt.comment) || + (typeof opt.comment === "string" && INVALID_RUNE.includes(opt.comment)) || opt.comma === opt.comment ) { throw new Error("Invalid Delimiter"); @@ -122,7 +122,7 @@ export async function readMatrix( } ): Promise<string[][]> { const result: string[][] = []; - let _nbFields: number; + let _nbFields: number | undefined; let lineResult: string[]; let first = true; let lineIndex = 0; @@ -253,8 +253,10 @@ export async function parse( }); } if (opt.parse) { - assert(opt.parse != null, "opt.parse must be set"); - return r.map((e: string[]): unknown => opt.parse(e)); + return r.map((e: string[]): unknown => { + assert(opt.parse, "opt.parse must be set"); + return opt.parse(e); + }); } return r; } diff --git a/std/encoding/csv_test.ts b/std/encoding/csv_test.ts index 74ba8face..efea353e1 100644 --- a/std/encoding/csv_test.ts +++ b/std/encoding/csv_test.ts @@ -476,26 +476,32 @@ for (const t of testCases) { if (t.Error) { let err; try { - actual = await readMatrix(new BufReader(new StringReader(t.Input)), { - comma: comma, - comment: comment, - trimLeadingSpace: trim, - fieldsPerRecord: fieldsPerRec, - lazyQuotes: lazyquote - }); + actual = await readMatrix( + new BufReader(new StringReader(t.Input ?? "")), + { + comma: comma, + comment: comment, + trimLeadingSpace: trim, + fieldsPerRecord: fieldsPerRec, + lazyQuotes: lazyquote + } + ); } catch (e) { err = e; } assert(err); assertEquals(err.message, t.Error); } else { - actual = await readMatrix(new BufReader(new StringReader(t.Input)), { - comma: comma, - comment: comment, - trimLeadingSpace: trim, - fieldsPerRecord: fieldsPerRec, - lazyQuotes: lazyquote - }); + actual = await readMatrix( + new BufReader(new StringReader(t.Input ?? "")), + { + comma: comma, + comment: comment, + trimLeadingSpace: trim, + fieldsPerRecord: fieldsPerRec, + lazyQuotes: lazyquote + } + ); const expected = t.Output; assertEquals(actual, expected); } diff --git a/std/encoding/yaml/loader/loader.ts b/std/encoding/yaml/loader/loader.ts index 556bd5b47..7db72a01d 100644 --- a/std/encoding/yaml/loader/loader.ts +++ b/std/encoding/yaml/loader/loader.ts @@ -187,7 +187,7 @@ interface DirectiveHandlers { [directive: string]: ( state: LoaderState, name: string, - ...args: unknown[] + ...args: string[] ) => void; } @@ -362,7 +362,7 @@ function storeMappingPair( mergeMappings(state, result, valueNode[index], overridableKeys); } } else { - mergeMappings(state, result, valueNode, overridableKeys); + mergeMappings(state, result, valueNode as ArrayObject, overridableKeys); } } else { if ( @@ -1610,7 +1610,7 @@ function readDocument(state: LoaderState): void { const documentStart = state.position; let position: number, directiveName: string, - directiveArgs: unknown[], + directiveArgs: string[], hasDirectives = false, ch: number; diff --git a/std/examples/gist.ts b/std/examples/gist.ts index ead97c7e2..8fc97e0f8 100755 --- a/std/examples/gist.ts +++ b/std/examples/gist.ts @@ -24,7 +24,7 @@ if (parsedArgs._.length === 0) { Deno.exit(1); } -const files = {}; +const files: Record<string, { content: string }> = {}; for (const filename of parsedArgs._) { const base = pathBase(filename); const content = await Deno.readFile(filename); diff --git a/std/fs/copy.ts b/std/fs/copy.ts index 62e6f59e5..86fac78df 100644 --- a/std/fs/copy.ts +++ b/std/fs/copy.ts @@ -85,6 +85,8 @@ async function copyFile( await Deno.copyFile(src, dest); if (options.preserveTimestamps) { const statInfo = await Deno.stat(src); + assert(statInfo.accessed != null, `statInfo.accessed is unavailable`); + assert(statInfo.modified != null, `statInfo.modified is unavailable`); await Deno.utime(dest, statInfo.accessed, statInfo.modified); } } diff --git a/std/fs/empty_dir_test.ts b/std/fs/empty_dir_test.ts index b27ebd033..928ba80e6 100644 --- a/std/fs/empty_dir_test.ts +++ b/std/fs/empty_dir_test.ts @@ -1,5 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { + assert, assertEquals, assertStrContains, assertThrows, @@ -225,6 +226,8 @@ Deno.test(async function emptyDirPermission(): Promise<void> { args: args }); + assert(stdout); + const output = await Deno.readAll(stdout); assertStrContains(new TextDecoder().decode(output), s.output); diff --git a/std/fs/exists_test.ts b/std/fs/exists_test.ts index 06b908b9d..204799447 100644 --- a/std/fs/exists_test.ts +++ b/std/fs/exists_test.ts @@ -131,7 +131,7 @@ Deno.test(async function existsPermission(): Promise<void> { args: args }); - const output = await Deno.readAll(stdout); + const output = await Deno.readAll(stdout!); assertStrContains(new TextDecoder().decode(output), s.output); } diff --git a/std/fs/walk.ts b/std/fs/walk.ts index 108eebc46..890114525 100644 --- a/std/fs/walk.ts +++ b/std/fs/walk.ts @@ -65,9 +65,9 @@ export async function* walk( includeFiles = true, includeDirs = true, followSymlinks = false, - exts = null, - match = null, - skip = null + exts = undefined, + match = undefined, + skip = undefined }: WalkOptions = {} ): AsyncIterableIterator<WalkInfo> { if (maxDepth < 0) { @@ -76,7 +76,7 @@ export async function* walk( if (includeDirs && include(root, exts, match, skip)) { yield { filename: root, info: await stat(root) }; } - if (maxDepth < 1 || !include(root, null, null, skip)) { + if (maxDepth < 1 || !include(root, undefined, undefined, skip)) { return; } const ls: FileInfo[] = await readDir(root); @@ -119,9 +119,9 @@ export function* walkSync( includeFiles = true, includeDirs = true, followSymlinks = false, - exts = null, - match = null, - skip = null + exts = undefined, + match = undefined, + skip = undefined }: WalkOptions = {} ): IterableIterator<WalkInfo> { if (maxDepth < 0) { @@ -130,7 +130,7 @@ export function* walkSync( if (includeDirs && include(root, exts, match, skip)) { yield { filename: root, info: statSync(root) }; } - if (maxDepth < 1 || !include(root, null, null, skip)) { + if (maxDepth < 1 || !include(root, undefined, undefined, skip)) { return; } const ls: FileInfo[] = readDirSync(root); diff --git a/std/http/cookie.ts b/std/http/cookie.ts index 5e4f38a29..10c9bd689 100644 --- a/std/http/cookie.ts +++ b/std/http/cookie.ts @@ -45,7 +45,7 @@ function toString(cookie: Cookie): string { if (cookie.httpOnly) { out.push("HttpOnly"); } - if (Number.isInteger(cookie.maxAge)) { + if (typeof cookie.maxAge === "number" && Number.isInteger(cookie.maxAge)) { assert(cookie.maxAge > 0, "Max-Age must be an integer superior to 0"); out.push(`Max-Age=${cookie.maxAge}`); } diff --git a/std/http/file_server.ts b/std/http/file_server.ts index d71b9ad53..aa0ff49da 100755 --- a/std/http/file_server.ts +++ b/std/http/file_server.ts @@ -15,6 +15,7 @@ import { Response } from "./server.ts"; import { parse } from "../flags/mod.ts"; +import { assert } from "../testing/asserts.ts"; interface EntryInfo { mode: string; @@ -40,10 +41,10 @@ const encoder = new TextEncoder(); const serverArgs = parse(args) as FileServerArgs; const CORSEnabled = serverArgs.cors ? true : false; -const target = posix.resolve(serverArgs._[1] || ""); -const addr = `0.0.0.0:${serverArgs.port || serverArgs.p || 4500}`; +const target = posix.resolve(serverArgs._[1] ?? ""); +const addr = `0.0.0.0:${serverArgs.port ?? serverArgs.p ?? 4500}`; -if (serverArgs.h || serverArgs.help) { +if (serverArgs.h ?? serverArgs.help) { console.log(`Deno File Server Serves a local directory in HTTP. @@ -125,8 +126,8 @@ async function serveDir( const listEntry: EntryInfo[] = []; const fileInfos = await readDir(dirPath); for (const fileInfo of fileInfos) { - const filePath = posix.join(dirPath, fileInfo.name); - const fileUrl = posix.join(dirUrl, fileInfo.name); + const filePath = posix.join(dirPath, fileInfo.name ?? ""); + const fileUrl = posix.join(dirUrl, fileInfo.name ?? ""); if (fileInfo.name === "index.html" && fileInfo.isFile()) { // in case index.html as dir... return await serveFile(req, filePath); @@ -139,7 +140,7 @@ async function serveDir( listEntry.push({ mode: modeToString(fileInfo.isDirectory(), mode), size: fileInfo.isFile() ? fileLenToString(fileInfo.len) : "", - name: fileInfo.name, + name: fileInfo.name ?? "", url: fileUrl }); } @@ -311,7 +312,7 @@ listenAndServe( } const fsPath = posix.join(target, normalizedUrl); - let response: Response; + let response: Response | undefined; try { const info = await stat(fsPath); if (info.isDirectory()) { @@ -324,10 +325,11 @@ listenAndServe( response = await serveFallback(req, e); } finally { if (CORSEnabled) { + assert(response); setCORS(response); } - serverLog(req, response); - req.respond(response); + serverLog(req, response!); + req.respond(response!); } } ); diff --git a/std/http/file_server_test.ts b/std/http/file_server_test.ts index 0329168e7..7c60d5f56 100644 --- a/std/http/file_server_test.ts +++ b/std/http/file_server_test.ts @@ -38,7 +38,7 @@ test(async function serveFile(): Promise<void> { assert(res.headers.has("access-control-allow-origin")); assert(res.headers.has("access-control-allow-headers")); assert(res.headers.has("content-type")); - assert(res.headers.get("content-type").includes("charset=utf-8")); + assert(res.headers.get("content-type")!.includes("charset=utf-8")); const downloadedFile = await res.text(); const localFile = new TextDecoder().decode( await Deno.readFile("README.md") diff --git a/std/http/server.ts b/std/http/server.ts index c6a895a1f..9e9cde016 100644 --- a/std/http/server.ts +++ b/std/http/server.ts @@ -436,7 +436,7 @@ export class Server implements AsyncIterable<ServerRequest> { ): AsyncIterableIterator<ServerRequest> { const bufr = new BufReader(conn); const w = new BufWriter(conn); - let req: ServerRequest | Deno.EOF; + let req: ServerRequest | Deno.EOF | undefined; let err: Error | undefined; while (!this.closing) { diff --git a/std/http/server_test.ts b/std/http/server_test.ts index 123bc7155..89aaca4ea 100644 --- a/std/http/server_test.ts +++ b/std/http/server_test.ts @@ -545,7 +545,7 @@ test(async function testReadRequestError(): Promise<void> { for (const test of testCases) { const reader = new BufReader(new StringReader(test.in)); let err; - let req: ServerRequest | Deno.EOF; + let req: ServerRequest | Deno.EOF | undefined; try { req = await readRequest(mockConn as Deno.Conn, reader); } catch (e) { @@ -559,7 +559,7 @@ test(async function testReadRequestError(): Promise<void> { assert(err instanceof (test.err as typeof UnexpectedEOFError)); } else { assert(req instanceof ServerRequest); - assert(test.headers != null); + assert(test.headers); assertEquals(err, undefined); assertNotEquals(req, Deno.EOF); for (const h of test.headers) { @@ -719,6 +719,7 @@ if (Deno.build.os !== "win") { const serverRoutine = async (): Promise<void> => { let reqCount = 0; const server = serve(":8124"); + // @ts-ignore const serverRid = server.listener["rid"]; let connRid = -1; for await (const req of server) { diff --git a/std/io/bufio.ts b/std/io/bufio.ts index c0a52ac6a..fa0ba7e73 100644 --- a/std/io/bufio.ts +++ b/std/io/bufio.ts @@ -311,7 +311,7 @@ export class BufReader implements Reader { */ async readSlice(delim: number): Promise<Uint8Array | Deno.EOF> { let s = 0; // search start index - let slice: Uint8Array; + let slice: Uint8Array | undefined; while (true) { // Search buffer. diff --git a/std/manual.md b/std/manual.md index 78037ad1e..99feef15b 100644 --- a/std/manual.md +++ b/std/manual.md @@ -1538,7 +1538,7 @@ Build with Cargo: cargo build -vv # Run: -./target/debug/deno tests/002_hello.ts +./target/debug/deno cli/tests/002_hello.ts ``` #### Testing and Tools diff --git a/std/node/events.ts b/std/node/events.ts index f4b3e0bc5..b2f1d6026 100644 --- a/std/node/events.ts +++ b/std/node/events.ts @@ -22,6 +22,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. import { validateIntegerRange } from "./util.ts"; +import { assert } from "../testing/asserts.ts"; export interface WrappedFunction extends Function { listener: Function; @@ -163,7 +164,8 @@ export default class EventEmitter { private unwrapListeners(arr: Function[]): Function[] { const unwrappedListeners: Function[] = new Array(arr.length) as Function[]; for (let i = 0; i < arr.length; i++) { - unwrappedListeners[i] = arr[i]["listener"] || arr[i]; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + unwrappedListeners[i] = (arr[i] as any)["listener"] || arr[i]; } return unwrappedListeners; } @@ -232,10 +234,12 @@ export default class EventEmitter { const wrapperContext = { eventName: eventName, listener: listener, - rawListener: wrapper, + rawListener: (wrapper as unknown) as WrappedFunction, context: this }; - const wrapped = wrapper.bind(wrapperContext); + const wrapped = (wrapper.bind( + wrapperContext + ) as unknown) as WrappedFunction; wrapperContext.rawListener = wrapped; wrapped.listener = listener; return wrapped as WrappedFunction; @@ -275,7 +279,7 @@ export default class EventEmitter { return this; } - if (this._events.has(eventName)) { + if (eventName && this._events.has(eventName)) { const listeners = (this._events.get(eventName) as Array< Function | WrappedFunction >).slice(); // Create a copy; We use it AFTER it's deleted. @@ -299,14 +303,19 @@ export default class EventEmitter { */ public removeListener(eventName: string | symbol, listener: Function): this { if (this._events.has(eventName)) { - const arr: Array<Function | WrappedFunction> = this._events.get( - eventName - ); + const arr: + | Array<Function | WrappedFunction> + | undefined = this._events.get(eventName); + + assert(arr); let listenerIndex = -1; for (let i = arr.length - 1; i >= 0; i--) { // arr[i]["listener"] is the reference to the listener inside a bound 'once' wrapper - if (arr[i] == listener || arr[i]["listener"] == listener) { + if ( + arr[i] == listener || + (arr[i] && (arr[i] as WrappedFunction)["listener"] == listener) + ) { listenerIndex = i; break; } @@ -421,8 +430,10 @@ export function on( ): AsyncInterable { // eslint-disable-next-line @typescript-eslint/no-explicit-any const unconsumedEventValues: any[] = []; - const unconsumedPromises = []; - let error = null; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const unconsumedPromises: any[] = []; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let error: Error | null = null; let finished = false; const iterator = { @@ -476,7 +487,7 @@ export function on( }, // eslint-disable-next-line @typescript-eslint/no-explicit-any - [Symbol.asyncIterator](): AsyncIterable<any> { + [Symbol.asyncIterator](): any { return this; } }; diff --git a/std/node/events_test.ts b/std/node/events_test.ts index c89df298a..b0b74e499 100644 --- a/std/node/events_test.ts +++ b/std/node/events_test.ts @@ -17,7 +17,7 @@ test({ fn() { let eventsFired: string[] = []; const testEmitter = new EventEmitter(); - testEmitter.on("newListener", event => { + testEmitter.on("newListener", (event: string) => { if (event !== "newListener") { eventsFired.push("newListener"); } @@ -81,20 +81,23 @@ test({ fn() { const testEmitter = new EventEmitter(); const eventsFired: string[] = []; - testEmitter.on("event", oneArg => { + testEmitter.on("event", (oneArg: string) => { eventsFired.push("event(" + oneArg + ")"); }); - testEmitter.on("event", (oneArg, twoArg) => { + testEmitter.on("event", (oneArg: string, twoArg: string) => { eventsFired.push("event(" + oneArg + ", " + twoArg + ")"); }); testEmitter.on("non-event", shouldNeverBeEmitted); - testEmitter.on("event", (oneArg, twoArg, threeArg) => { - eventsFired.push( - "event(" + oneArg + ", " + twoArg + ", " + threeArg + ")" - ); - }); + testEmitter.on( + "event", + (oneArg: string, twoArg: string, threeArg: string) => { + eventsFired.push( + "event(" + oneArg + ", " + twoArg + ", " + threeArg + ")" + ); + } + ); testEmitter.emit("event", 1, 2, 3); assertEquals(eventsFired, ["event(1)", "event(1, 2)", "event(1, 2, 3)"]); } diff --git a/std/node/global.ts b/std/node/global.ts index c21b0b659..c889e9c8d 100644 --- a/std/node/global.ts +++ b/std/node/global.ts @@ -1 +1,2 @@ -window["global"] = window; +// @ts-ignore +globalThis["global"] = globalThis; diff --git a/std/node/module.ts b/std/node/module.ts index ac436c555..547c76bab 100644 --- a/std/node/module.ts +++ b/std/node/module.ts @@ -40,7 +40,7 @@ const isWindows = path.isWindows; const relativeResolveCache = Object.create(null); let requireDepth = 0; -let statCache = null; +let statCache: Map<string, StatResult> | null = null; type StatResult = -1 | 0 | 1; // Returns 0 if the path refers to @@ -64,7 +64,11 @@ function stat(filename: string): StatResult { } } -function updateChildren(parent: Module, child: Module, scan: boolean): void { +function updateChildren( + parent: Module | null, + child: Module, + scan: boolean +): void { const children = parent && parent.children; if (children && !(scan && children.includes(child))) { children.push(child); @@ -75,17 +79,17 @@ class Module { id: string; // eslint-disable-next-line @typescript-eslint/no-explicit-any exports: any; - parent?: Module; - filename: string; + parent: Module | null; + filename: string | null; loaded: boolean; children: Module[]; paths: string[]; path: string; - constructor(id = "", parent?: Module) { + constructor(id = "", parent?: Module | null) { this.id = id; this.exports = {}; - this.parent = parent; - updateChildren(parent, this, false); + this.parent = parent || null; + updateChildren(parent || null, this, false); this.filename = null; this.loaded = false; this.children = []; @@ -229,25 +233,25 @@ class Module { fakeParent.paths = Module._nodeModulePaths(path); const lookupPaths = Module._resolveLookupPaths(request, fakeParent); - for (let j = 0; j < lookupPaths.length; j++) { - if (!paths.includes(lookupPaths[j])) paths.push(lookupPaths[j]); + for (let j = 0; j < lookupPaths!.length; j++) { + if (!paths.includes(lookupPaths![j])) paths.push(lookupPaths![j]); } } } } else if (options.paths === undefined) { - paths = Module._resolveLookupPaths(request, parent); + paths = Module._resolveLookupPaths(request, parent)!; } else { throw new Error("options.paths is invalid"); } } else { - paths = Module._resolveLookupPaths(request, parent); + paths = Module._resolveLookupPaths(request, parent)!; } // Look up the filename first, since that's the cache key. const filename = Module._findPath(request, paths, isMain); if (!filename) { const requireStack = []; - for (let cursor = parent; cursor; cursor = cursor.parent) { + for (let cursor: Module | null = parent; cursor; cursor = cursor.parent) { requireStack.push(cursor.filename || cursor.id); } let message = `Cannot find module '${request}'`; @@ -341,7 +345,7 @@ class Module { // object. // eslint-disable-next-line @typescript-eslint/no-explicit-any static _load(request: string, parent: Module, isMain: boolean): any { - let relResolveCacheIdentifier; + let relResolveCacheIdentifier: string | undefined; if (parent) { // Fast path for (lazy loaded) modules in the same directory. The indirect // caching is required to allow cache invalidation without changing the old @@ -385,6 +389,7 @@ class Module { Module._cache[filename] = module; if (parent !== undefined) { + assert(relResolveCacheIdentifier); relativeResolveCache[relResolveCacheIdentifier] = filename; } @@ -397,6 +402,7 @@ class Module { if (threw) { delete Module._cache[filename]; if (parent !== undefined) { + assert(relResolveCacheIdentifier); delete relativeResolveCache[relResolveCacheIdentifier]; } } else if ( @@ -602,7 +608,7 @@ for (const id of nativeModulePolyfill.keys()) { Module.builtinModules.push(id); } -let modulePaths = []; +let modulePaths: string[] = []; // Given a module name, and a list of paths to test, returns the first // matching file in the following precedence. @@ -664,7 +670,7 @@ function readPackage(requestPath: string): PackageInfo | null { } function readPackageScope( - checkPath + checkPath: string ): { path: string; data: PackageInfo } | false { const rootSeparatorIndex = checkPath.indexOf(path.sep); let separatorIndex; @@ -987,6 +993,7 @@ const CircularRequirePrototypeWarningProxy = new Proxy( { // eslint-disable-next-line @typescript-eslint/no-explicit-any get(target, prop): any { + // @ts-ignore if (prop in target) return target[prop]; emitCircularRequireWarning(prop); return undefined; @@ -1150,7 +1157,7 @@ function getPathFromURLWin32(url: URL): string { let pathname = url.pathname; for (let n = 0; n < pathname.length; n++) { if (pathname[n] === "%") { - const third = pathname.codePointAt(n + 2) | 0x20; + const third = pathname.codePointAt(n + 2)! | 0x20; if ( (pathname[n + 1] === "2" && third === 102) || // 2f 2F / (pathname[n + 1] === "5" && third === 99) @@ -1165,7 +1172,7 @@ function getPathFromURLWin32(url: URL): string { pathname = pathname.replace(forwardSlashRegEx, "\\"); pathname = decodeURIComponent(pathname); // TODO: handle windows hostname case (needs bindings) - const letter = pathname.codePointAt(1) | 0x20; + const letter = pathname.codePointAt(1)! | 0x20; const sep = pathname[2]; if ( letter < CHAR_LOWERCASE_A || @@ -1184,7 +1191,7 @@ function getPathFromURLPosix(url: URL): string { const pathname = url.pathname; for (let n = 0; n < pathname.length; n++) { if (pathname[n] === "%") { - const third = pathname.codePointAt(n + 2) | 0x20; + const third = pathname.codePointAt(n + 2)! | 0x20; if (pathname[n + 1] === "2" && third === 102) { throw new Error( "Invalid file URL path: must not include encoded / characters" diff --git a/std/node/os.ts b/std/node/os.ts index e4a00c450..3bff03a69 100644 --- a/std/node/os.ts +++ b/std/node/os.ts @@ -123,7 +123,7 @@ export function getPriority(pid = 0): number { } /** Returns the string path of the current user's home directory. */ -export function homedir(): string { +export function homedir(): string | null { return Deno.dir("home"); } @@ -157,7 +157,7 @@ export function release(): string { /** Not yet implemented */ export function setPriority(pid: number, priority?: number): void { - /* The node API has the 'pid' as the first parameter and as optional. + /* The node API has the 'pid' as the first parameter and as optional. This makes for a problematic implementation in Typescript. */ if (priority === undefined) { priority = pid; diff --git a/std/path/utils.ts b/std/path/utils.ts index 9911f5347..cb1c14c16 100644 --- a/std/path/utils.ts +++ b/std/path/utils.ts @@ -46,13 +46,13 @@ export function normalizeString( let lastSegmentLength = 0; let lastSlash = -1; let dots = 0; - let code: number; + let code: number | undefined; for (let i = 0, len = path.length; i <= len; ++i) { if (i < len) code = path.charCodeAt(i); - else if (isPathSeparator(code)) break; + else if (isPathSeparator(code!)) break; else code = CHAR_FORWARD_SLASH; - if (isPathSeparator(code)) { + if (isPathSeparator(code!)) { if (lastSlash === i - 1 || dots === 1) { // NOOP } else if (lastSlash !== i - 1 && dots === 2) { diff --git a/std/path/win32.ts b/std/path/win32.ts index 11518ee7c..2f28d22c1 100644 --- a/std/path/win32.ts +++ b/std/path/win32.ts @@ -303,7 +303,7 @@ export function join(...paths: string[]): string { if (pathsCount === 0) return "."; let joined: string | undefined; - let firstPart: string; + let firstPart: string | null = null; for (let i = 0; i < pathsCount; ++i) { const path = paths[i]; assertPath(path); diff --git a/std/textproto/mod.ts b/std/textproto/mod.ts index 465753823..dd7d3ede9 100644 --- a/std/textproto/mod.ts +++ b/std/textproto/mod.ts @@ -67,7 +67,7 @@ export class TextProtoReader { */ async readMIMEHeader(): Promise<Headers | Deno.EOF> { const m = new Headers(); - let line: Uint8Array; + let line: Uint8Array | undefined; // The first line cannot start with a leading space. let buf = await this.r.peek(1); @@ -135,7 +135,7 @@ export class TextProtoReader { async readLineSlice(): Promise<Uint8Array | Deno.EOF> { // this.closeDot(); - let line: Uint8Array; + let line: Uint8Array | undefined; while (true) { const r = await this.r.readLine(); if (r === Deno.EOF) return Deno.EOF; diff --git a/std/util/deep_assign.ts b/std/util/deep_assign.ts index 9b57e45dc..9034d89bd 100644 --- a/std/util/deep_assign.ts +++ b/std/util/deep_assign.ts @@ -1,4 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +import { assert } from "../testing/asserts.ts"; + export function deepAssign( target: Record<string, unknown>, ...sources: object[] @@ -24,6 +26,7 @@ export function deepAssign( if (typeof target[key] !== `object` || !target[key]) { target[key] = {}; } + assert(value); deepAssign(target[key] as Record<string, unknown>, value); }); } |