From fadc39fc5c1f256da99baaff0b7dd4dd637a6d74 Mon Sep 17 00:00:00 2001 From: timongh <46739861+timongh@users.noreply.github.com> Date: Sun, 29 Jan 2023 18:06:00 +0800 Subject: [PATCH] add ts config: noImplicitThis --- .../custom-navbar/feeds/tabs/next-page.ts | 11 ++- .../components/style/home-redesign/mixin.ts | 18 ++-- .../video/download/inputs/episode-item.ts | 2 +- src/core/utils/index.ts | 84 ++++++++++--------- src/core/utils/log.ts | 12 +-- tsconfig.json | 1 + 6 files changed, 68 insertions(+), 60 deletions(-) diff --git a/registry/lib/components/style/custom-navbar/feeds/tabs/next-page.ts b/registry/lib/components/style/custom-navbar/feeds/tabs/next-page.ts index ff921770d..52e868039 100644 --- a/registry/lib/components/style/custom-navbar/feeds/tabs/next-page.ts +++ b/registry/lib/components/style/custom-navbar/feeds/tabs/next-page.ts @@ -23,12 +23,12 @@ export const nextPageMixin = ( data() { return { loading: true, - cards: [], + cards: [] as MappedItem[], hasMorePage: true, } }, computed: { - sortedCards() { + sortedCards(): MappedItem[] { return ([...this.cards] as MappedItem[]).sort(descendingStringSort(it => it.id)) }, }, @@ -42,6 +42,9 @@ export const nextPageMixin = ( }, methods: { async nextPage() { + const this0 = this as typeof this & { + onCardsUpdate?: (cards: MappedItem[]) => MappedItem[] + } try { const cards: MappedItem[] = this.sortedCards const lastCardID = cards[cards.length - 1]?.id ?? 0 @@ -61,8 +64,8 @@ export const nextPageMixin = ( .filter(card => !isPreOrderedVideo(card)), ) - if (concatCards.length > 0 && this.onCardsUpdate) { - concatCards = this.onCardsUpdate(concatCards) + if (concatCards.length > 0 && this0.onCardsUpdate) { + concatCards = this0.onCardsUpdate(concatCards) } console.log('nextPage get', concatCards) this.cards = concatCards diff --git a/registry/lib/components/style/home-redesign/mixin.ts b/registry/lib/components/style/home-redesign/mixin.ts index 1eb7a160b..978de41e0 100644 --- a/registry/lib/components/style/home-redesign/mixin.ts +++ b/registry/lib/components/style/home-redesign/mixin.ts @@ -3,9 +3,9 @@ import { getJson } from '@/core/ajax' /** * 封装一些 API 请求的通用行为, 使用者要定义 parseJson 方法将返回的 JSON 转换为数据数组, 会自动存到 this.items 里 */ -export const requestMixin = ( +export const requestMixin = ( config: { - requestMethod?: (url: string) => Promise + requestMethod?: (url: string) => Promise } = {}, ) => { const { requestMethod = getJson } = config @@ -18,28 +18,28 @@ export const requestMixin = ( }, data() { return { - items: [], + items: [] as I[], loading: true, error: false, } }, computed: { - loaded() { + loaded(): boolean { return !this.loading && !this.error }, }, created() { - this.reload() + this.reload().then() }, methods: { async reload() { + const this0 = this as typeof this & { parseJson: (json: D) => I[]; itemLimit?: number } try { this.error = false this.loading = true - this.items = this.parseJson(await requestMethod(this.api)).slice( - 0, - this.itemLimit ?? Infinity, - ) + this.items = this0 + .parseJson(await requestMethod(this.api)) + .slice(0, this0.itemLimit ?? Infinity) } catch (error) { console.error(error) this.error = true diff --git a/registry/lib/components/video/download/inputs/episode-item.ts b/registry/lib/components/video/download/inputs/episode-item.ts index bff349e09..2cfbf9fe3 100644 --- a/registry/lib/components/video/download/inputs/episode-item.ts +++ b/registry/lib/components/video/download/inputs/episode-item.ts @@ -14,7 +14,7 @@ export const createEpisodesPicker = ( Vue.extend({ computed: { checkedInputItems() { - return this.$refs.picker.checkedInputItems + return (this.$refs.picker as any).checkedInputItems }, }, render(createElement) { diff --git a/src/core/utils/index.ts b/src/core/utils/index.ts index 938f9765d..e8d50c88c 100644 --- a/src/core/utils/index.ts +++ b/src/core/utils/index.ts @@ -4,7 +4,7 @@ import type { VueModule } from '../common-types' * 当查询 video 元素且被灰度了 WasmPlayer 时, 更换为对 bwp-video 的查询, 否则会找不到 video 元素 * @param selector 选择器 */ -export const bwpVideoFilter = (selector: string) => { +export const bwpVideoFilter = (selector: string): string => { // if (!unsafeWindow.__ENABLE_WASM_PLAYER__) { // return selector // } @@ -24,44 +24,46 @@ interface DocumentQuerySelector { * 同 `document.querySelector`, 对 `` 有额外处理 * @param selector 选择器 */ - (selector: string): Element | null + (selector: string): E | null /** * 在指定元素上进行 `querySelector`, 对 `` 有额外处理 - * @param selector 元素 + * @param element 元素 * @param scopedSelector 选择器 */ - (element: Element, scopedSelector: string): Element | null + (element: Element, scopedSelector: string): E | null } -export const dq: DocumentQuerySelector = ( +export const dq: DocumentQuerySelector = ( selectorOrElement: string | Element, scopedSelector?: string, -) => { +): E => { if (!scopedSelector) { - return document.querySelector(bwpVideoFilter(selectorOrElement as string)) + return document.querySelector(bwpVideoFilter(selectorOrElement as string)) } - return (selectorOrElement as Element).querySelector(bwpVideoFilter(scopedSelector)) + return (selectorOrElement as Element).querySelector(bwpVideoFilter(scopedSelector)) } interface DocumentQuerySelectorAll { /** * 同 `document.querySelectorAll` (返回转换过的真数组), 对 `` 有额外处理 * @param selector 选择器 */ - (selector: string): Element[] + (selector: string): E[] /** * 在指定元素上进行`querySelectorAll` (返回转换过的真数组), 对 `` 有额外处理 * @param selector 元素 * @param scopedSelector 选择器 */ - (element: Element, scopedSelector: string): Element[] + (element: Element, scopedSelector: string): E[] } -export const dqa: DocumentQuerySelectorAll = ( +export const dqa: DocumentQuerySelectorAll = ( selectorOrElement: Element | string, scopedSelector?: string, -) => { +): E[] => { if (!scopedSelector) { - return Array.from(document.querySelectorAll(bwpVideoFilter(selectorOrElement as string))) + return Array.from(document.querySelectorAll(bwpVideoFilter(selectorOrElement as string))) } - return Array.from((selectorOrElement as Element).querySelectorAll(bwpVideoFilter(scopedSelector))) + return Array.from( + (selectorOrElement as Element).querySelectorAll(bwpVideoFilter(scopedSelector)), + ) } interface DocumentEvaluate { (xpathExpression: string): XPathResult @@ -74,8 +76,8 @@ export const de: DocumentEvaluate = ( contextNode?: Node, type?: number, result?: XPathResult, -) => document.evaluate(xpathExpression, contextNode, null, type, result) -interface DocumentEvaluateAll { +): XPathResult => document.evaluate(xpathExpression, contextNode, null, type, result) +type DocumentEvaluateAll = { (xpathExpression: string): Node[] (xpathExpression: string, contextNode: Node): Node[] (xpathExpression: string, contextNode: Node, order: boolean): Node[] @@ -86,7 +88,7 @@ export const dea: DocumentEvaluateAll = ( contextNode?: Node, order?: boolean, result?: XPathResult, -) => { +): Node[] => { const xpathResult = de( xpathExpression, contextNode, @@ -96,18 +98,12 @@ export const dea: DocumentEvaluateAll = ( return Array.from({ length: xpathResult.snapshotLength }, (_, i) => xpathResult.snapshotItem(i)) } -interface DocumentEvaluateAllIterable { - (xpathExpression: string): Iterable - (xpathExpression: string, contextNode: Node): Iterable - (xpathExpression: string, contextNode: Node, order: boolean): Iterable - (xpathExpression: string, contextNode: Node, order: boolean, result: XPathResult): Iterable -} -export const deai: DocumentEvaluateAllIterable = ( +function* deaiRaw( xpathExpression: string, contextNode?: Node, order?: boolean, result?: XPathResult, -) => { +): Generator { const xpathResult = de( xpathExpression, contextNode, @@ -115,20 +111,28 @@ export const deai: DocumentEvaluateAllIterable = ( result, ) - return { - [Symbol.iterator]: () => ({ - next: () => { - let node = null - do { - node = xpathResult.iterateNext() - return node - ? ({ done: false, value: node } as { done: false; value: Node }) - : ({ done: true } as { done: true; value: any }) - } while (node) - }, - }), + let node = null + for (;;) { + node = xpathResult.iterateNext() + if (node) { + yield node + } else { + break + } } } +interface DocumentEvaluateAllIterable { + (xpathExpression: string): IterableIterator + (xpathExpression: string, contextNode: Node): IterableIterator + (xpathExpression: string, contextNode: Node, order: boolean): IterableIterator + ( + xpathExpression: string, + contextNode: Node, + order: boolean, + result: XPathResult, + ): IterableIterator +} +export const deai: DocumentEvaluateAllIterable = deaiRaw interface DocumentEvaluateSingle { (xpathExpression: string): T | null (xpathExpression: string, contextNode: Node): T | null @@ -138,7 +142,7 @@ export const des: DocumentEvaluateSingle = ( xpathExpression: string, contextNode?: Node, result?: XPathResult, -) => +): T | null => de(xpathExpression, contextNode, XPathResult.FIRST_ORDERED_NODE_TYPE, result) .singleNodeValue as T | null /** 空函数 */ @@ -300,7 +304,7 @@ export const createHook = boolean, ) => { const original: (...args: HookParameters) => ReturnType = type[target] as any - type[target] = function hook(...args: HookParameters) { + type[target] = function hook(this: any, ...args: HookParameters) { const shouldCallOriginal = hookFunc(...args) if (!shouldCallOriginal) { return undefined @@ -321,7 +325,7 @@ export const createPostHook = unknown, ) => { const original: (...args: HookParameters) => ReturnType = type[target] as any - type[target] = function hook(...args: HookParameters) { + type[target] = function hook(this: any, ...args: HookParameters) { const result = original?.call(this, ...args) hookFunc(...args) return result diff --git a/src/core/utils/log.ts b/src/core/utils/log.ts index e09befa95..8f368a624 100644 --- a/src/core/utils/log.ts +++ b/src/core/utils/log.ts @@ -64,7 +64,7 @@ export const ScopedConsoleCallHook = 'scopedConsole.call' * 创建一个 ScopedConsole, 为输出的日志添加固定的前缀 * @param config 配置对象或者 scope 名称 */ -export const useScopedConsole = (config: ScopedConsoleConfig | string) => { +export const useScopedConsole = (config: ScopedConsoleConfig | string): Console => { const { before: beforeCreate, after: afterCreate } = getHook(ScopedConsoleCreateHook) const { name, @@ -78,7 +78,7 @@ export const useScopedConsole = (config: ScopedConsoleConfig | string) => { target: (...args: any[]) => void, prependConfig: ScopedConsoleConfig, firstColor = prependConfig.color, - ) => { + ): ((this: Console, ...args: unknown[]) => unknown) => { const lastScopedData: ScopedData = target[ScopedConsoleSymbol] const backgroundColor = (lastScopedData ? prependConfig.color : firstColor) ?? specialPalette.default @@ -98,7 +98,7 @@ export const useScopedConsole = (config: ScopedConsoleConfig | string) => { original: lastScopedData?.original ?? target, } const rootTarget = currentScopedData.original - const patchedLog = function patchedLog(...args: any[]) { + const patchedLog = function patchedLog(this: Console, ...args: unknown[]): unknown { const hookPayload = { type: rootTarget[NamePatchSymbol], args, @@ -126,9 +126,9 @@ export const useScopedConsole = (config: ScopedConsoleConfig | string) => { groupConfig: ScopedConsoleConfig, firstColor = groupConfig.color, counter: (num: number) => number = n => n, - ) => { + ): ((this: Console, ...args: unknown[]) => unknown) => { const patch = prependBadge(target, groupConfig, firstColor) - const patchedGroup = function patchedGroup(...args: any[]) { + const patchedGroup = function patchedGroup(this: Console, ...args: unknown[]): unknown { const returnValue = patch.apply(this, args) groupCounter = counter(groupCounter) return returnValue @@ -179,7 +179,7 @@ export const useScopedConsole = (config: ScopedConsoleConfig | string) => { ) scopedConsole.debug = (() => { const patch = prependBadge(console.debug, actualConfig) - return function patchedDebug(...args: any[]) { + return function patchedDebug(this: Console, ...args: unknown[]): unknown { if (!getGeneralSettings().devMode) { return undefined } diff --git a/tsconfig.json b/tsconfig.json index 02e8fb129..36925c71f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ "target": "ESNext", "strict": false, "noImplicitAny": false, + "noImplicitThis": true, "importsNotUsedAsValues": "error", "sourceMap": true, "baseUrl": ".",