diff --git a/encoding/base32_test.ts b/encoding/base32_test.ts index eb51e44ab0d7..28550d57a523 100644 --- a/encoding/base32_test.ts +++ b/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/encoding/csv.ts b/encoding/csv.ts index 1314afcaafb3..12336b10ddcc 100644 --- a/encoding/csv.ts +++ b/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 { 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/encoding/csv_test.ts b/encoding/csv_test.ts index 74ba8face2de..efea353e1635 100644 --- a/encoding/csv_test.ts +++ b/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/encoding/yaml/loader/loader.ts b/encoding/yaml/loader/loader.ts index 556bd5b475fc..7db72a01dc52 100644 --- a/encoding/yaml/loader/loader.ts +++ b/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/examples/gist.ts b/examples/gist.ts index ead97c7e2e81..8fc97e0f832c 100755 --- a/examples/gist.ts +++ b/examples/gist.ts @@ -24,7 +24,7 @@ if (parsedArgs._.length === 0) { Deno.exit(1); } -const files = {}; +const files: Record = {}; for (const filename of parsedArgs._) { const base = pathBase(filename); const content = await Deno.readFile(filename); diff --git a/fs/copy.ts b/fs/copy.ts index 62e6f59e541d..86fac78dff74 100644 --- a/fs/copy.ts +++ b/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/fs/empty_dir_test.ts b/fs/empty_dir_test.ts index b27ebd033d6f..928ba80e6bdd 100644 --- a/fs/empty_dir_test.ts +++ b/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 { args: args }); + assert(stdout); + const output = await Deno.readAll(stdout); assertStrContains(new TextDecoder().decode(output), s.output); diff --git a/fs/exists_test.ts b/fs/exists_test.ts index 06b908b9db79..204799447e5e 100644 --- a/fs/exists_test.ts +++ b/fs/exists_test.ts @@ -131,7 +131,7 @@ Deno.test(async function existsPermission(): Promise { args: args }); - const output = await Deno.readAll(stdout); + const output = await Deno.readAll(stdout!); assertStrContains(new TextDecoder().decode(output), s.output); } diff --git a/fs/walk.ts b/fs/walk.ts index 108eebc46654..89011452572f 100644 --- a/fs/walk.ts +++ b/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 { 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 { 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/http/cookie.ts b/http/cookie.ts index 5e4f38a29101..10c9bd689a02 100644 --- a/http/cookie.ts +++ b/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/http/file_server.ts b/http/file_server.ts index d71b9ad533b9..aa0ff49daa08 100755 --- a/http/file_server.ts +++ b/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/http/file_server_test.ts b/http/file_server_test.ts index 0329168e785a..7c60d5f5627f 100644 --- a/http/file_server_test.ts +++ b/http/file_server_test.ts @@ -38,7 +38,7 @@ test(async function serveFile(): Promise { 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/http/server.ts b/http/server.ts index c6a895a1fd86..9e9cde0168f9 100644 --- a/http/server.ts +++ b/http/server.ts @@ -436,7 +436,7 @@ export class Server implements AsyncIterable { ): AsyncIterableIterator { 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/http/server_test.ts b/http/server_test.ts index 123bc7155c9f..89aaca4ea355 100644 --- a/http/server_test.ts +++ b/http/server_test.ts @@ -545,7 +545,7 @@ test(async function testReadRequestError(): Promise { 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 { 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 => { 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/io/bufio.ts b/io/bufio.ts index c0a52ac6a4fd..fa0ba7e7351d 100644 --- a/io/bufio.ts +++ b/io/bufio.ts @@ -311,7 +311,7 @@ export class BufReader implements Reader { */ async readSlice(delim: number): Promise { let s = 0; // search start index - let slice: Uint8Array; + let slice: Uint8Array | undefined; while (true) { // Search buffer. diff --git a/manual.md b/manual.md index 78037ad1ece4..99feef15ba18 100644 --- a/manual.md +++ b/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/node/events.ts b/node/events.ts index f4b3e0bc590c..b2f1d60260dd 100644 --- a/node/events.ts +++ b/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 = this._events.get( - eventName - ); + const arr: + | Array + | 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 { + [Symbol.asyncIterator](): any { return this; } }; diff --git a/node/events_test.ts b/node/events_test.ts index c89df298aa9e..b0b74e499c1f 100644 --- a/node/events_test.ts +++ b/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/node/global.ts b/node/global.ts index c21b0b659690..c889e9c8dfdc 100644 --- a/node/global.ts +++ b/node/global.ts @@ -1 +1,2 @@ -window["global"] = window; +// @ts-ignore +globalThis["global"] = globalThis; diff --git a/node/module.ts b/node/module.ts index ac436c555204..547c76bab179 100644 --- a/node/module.ts +++ b/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 | 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/node/os.ts b/node/os.ts index e4a00c450d3d..3bff03a69c70 100644 --- a/node/os.ts +++ b/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/path/utils.ts b/path/utils.ts index 9911f5347d17..cb1c14c16148 100644 --- a/path/utils.ts +++ b/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/path/win32.ts b/path/win32.ts index 11518ee7c26f..2f28d22c19f4 100644 --- a/path/win32.ts +++ b/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/textproto/mod.ts b/textproto/mod.ts index 465753823990..dd7d3ede994d 100644 --- a/textproto/mod.ts +++ b/textproto/mod.ts @@ -67,7 +67,7 @@ export class TextProtoReader { */ async readMIMEHeader(): Promise { 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 { // 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/util/deep_assign.ts b/util/deep_assign.ts index 9b57e45dc8c4..9034d89bdf4e 100644 --- a/util/deep_assign.ts +++ b/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, ...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, value); }); }