From cabfeb8b9d715f040b04925f4ffed91296a7ebfa Mon Sep 17 00:00:00 2001 From: uhyo Date: Sat, 21 Nov 2020 18:24:03 +0900 Subject: [PATCH] fix: fix type errors in TS 4.1 --- package-lock.json | 6 +- package.json | 2 +- src/builder/PathRouteBuilder/index.ts | 15 +- src/builder/RouteRecord/PathRouteRecord.ts | 2 +- src/builder/SearchRouteBuilder/index.ts | 6 +- src/builder/SingleHashRouteBuilder/index.ts | 6 +- src/builder/StateRouteBuilder/index.ts | 6 +- src/core/BuilderLink/SegmentResolver.ts | 4 +- src/core/BuilderLink/index.ts | 10 +- src/core/RouteResolver/resolveChain.ts | 153 ++++++++++++-------- 10 files changed, 126 insertions(+), 84 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1262b88..d34999b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11214,9 +11214,9 @@ } }, "typescript": { - "version": "4.0.1-rc", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.1-rc.tgz", - "integrity": "sha512-TCkspT3dSKOykbzS3/WSK7pqU2h1d/lEO6i45Afm5Y3XNAEAo8YXTG3kHOQk/wFq/5uPyO1+X8rb/Q+g7UsxJw==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.2.tgz", + "integrity": "sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ==", "dev": true }, "uglify-js": { diff --git a/package.json b/package.json index 7633a6b..590438e 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "react": "^16.13.1", "react-dom": "^16.13.1", "standard-version": "^9.0.0", - "typescript": "^4.0.1-rc" + "typescript": "^4.1.2" }, "husky": { "hooks": { diff --git a/src/builder/PathRouteBuilder/index.ts b/src/builder/PathRouteBuilder/index.ts index 97e6532..e5e02af 100644 --- a/src/builder/PathRouteBuilder/index.ts +++ b/src/builder/PathRouteBuilder/index.ts @@ -64,7 +64,7 @@ export class PathRouteBuilder< AnyFlag extends WildcardFlagType, ExactFlag extends WildcardFlagType, Match -> implements AttachableRouteBuilder { +> implements AttachableRouteBuilder { static init(): PathRouteBuilder< ActionResult, {}, @@ -79,10 +79,15 @@ export class PathRouteBuilder< ); } - readonly #link: RouteBuilderLink; + readonly #link: RouteBuilderLink; #routes: RouteRecordsBase = Object.create(null); #wildcardRoute: - | MatchingRouteRecordObject + | MatchingRouteRecordObject< + ActionResult, + string | undefined, + Match, + boolean + > | undefined = undefined; #exactRoute: | PathRouteRecord @@ -214,7 +219,7 @@ export class PathRouteBuilder< action = a; return this; }, - attach(builder: AttachableRouteBuilder) { + attach(builder: AttachableRouteBuilder) { attachedBuilder = builder; // eslint-disable-next-line @typescript-eslint/no-explicit-any return builder as any; @@ -352,7 +357,7 @@ export class PathRouteBuilder< return this.#exactRoute as ExactRouteType; } - getBuilderLink(): RouteBuilderLink { + getBuilderLink(): RouteBuilderLink { return this.#link; } } diff --git a/src/builder/RouteRecord/PathRouteRecord.ts b/src/builder/RouteRecord/PathRouteRecord.ts index 228e8d6..3637e2c 100644 --- a/src/builder/RouteRecord/PathRouteRecord.ts +++ b/src/builder/RouteRecord/PathRouteRecord.ts @@ -14,7 +14,7 @@ export class PathRouteRecord readonly key: string | undefined; constructor( - parent: AttachableRouteBuilder, + parent: AttachableRouteBuilder, key: string | undefined, action: ActionTypeOfRouteRecord ) { diff --git a/src/builder/SearchRouteBuilder/index.ts b/src/builder/SearchRouteBuilder/index.ts index 350655b..3d4908e 100644 --- a/src/builder/SearchRouteBuilder/index.ts +++ b/src/builder/SearchRouteBuilder/index.ts @@ -32,7 +32,7 @@ export class SearchRouteBuilder< Match, WildcardFlagToHasAction > - implements AttachableRouteBuilder { + implements AttachableRouteBuilder { static init< ActionResult, Key extends string, @@ -76,7 +76,7 @@ export class SearchRouteBuilder< readonly matchKey: Extract; readonly optional: boolean; - #link: RouteBuilderLink; + #link: RouteBuilderLink; #route: RouteRecordType; private constructor( @@ -138,7 +138,7 @@ export class SearchRouteBuilder< return this.#route; } - getBuilderLink(): RouteBuilderLink { + getBuilderLink(): RouteBuilderLink { return this.#link; } } diff --git a/src/builder/SingleHashRouteBuilder/index.ts b/src/builder/SingleHashRouteBuilder/index.ts index 9c5101a..1a1ddba 100644 --- a/src/builder/SingleHashRouteBuilder/index.ts +++ b/src/builder/SingleHashRouteBuilder/index.ts @@ -31,7 +31,7 @@ export class SingleHashRouteBuilder< Match, WildcardFlagToHasAction > - implements AttachableRouteBuilder { + implements AttachableRouteBuilder { static init< ActionResult, Key extends string, @@ -74,7 +74,7 @@ export class SingleHashRouteBuilder< readonly matchKey: Extract; readonly optional: boolean; - #link: RouteBuilderLink; + #link: RouteBuilderLink; #route: RouteRecordType; private constructor( @@ -136,7 +136,7 @@ export class SingleHashRouteBuilder< return this.#route; } - getBuilderLink(): RouteBuilderLink { + getBuilderLink(): RouteBuilderLink { return this.#link; } } diff --git a/src/builder/StateRouteBuilder/index.ts b/src/builder/StateRouteBuilder/index.ts index 8875489..66edb59 100644 --- a/src/builder/StateRouteBuilder/index.ts +++ b/src/builder/StateRouteBuilder/index.ts @@ -33,7 +33,7 @@ export class StateRouteBuilder< Match, WildcardFlagToHasAction > - implements AttachableRouteBuilder { + implements AttachableRouteBuilder { static init< ActionResult, StateValue, @@ -85,7 +85,7 @@ export class StateRouteBuilder< readonly matchKey: Extract; - #link: RouteBuilderLink; + #link: RouteBuilderLink; #validator: Validator; #route: RouteRecordType; @@ -143,7 +143,7 @@ export class StateRouteBuilder< return this.#route; } - getBuilderLink(): RouteBuilderLink { + getBuilderLink(): RouteBuilderLink { return this.#link; } } diff --git a/src/core/BuilderLink/SegmentResolver.ts b/src/core/BuilderLink/SegmentResolver.ts index a46e618..658ab07 100644 --- a/src/core/BuilderLink/SegmentResolver.ts +++ b/src/core/BuilderLink/SegmentResolver.ts @@ -7,12 +7,12 @@ export type ResolvedSegmentType = // value: RouteRecordType; value: Value; // TODO: this `| undefined` could be removed? - link: BuilderLink | undefined; + link: BuilderLink | undefined; } | { type: "matching"; value: Value; - link: BuilderLink | undefined; + link: BuilderLink | undefined; matchKey: string; matchValue: Segment; }; diff --git a/src/core/BuilderLink/index.ts b/src/core/BuilderLink/index.ts index e5421bb..443428b 100644 --- a/src/core/BuilderLink/index.ts +++ b/src/core/BuilderLink/index.ts @@ -1,6 +1,10 @@ import { Location } from "../Location"; import type { LocationComposer } from "../LocationComposer"; import { RouteResolver } from "../RouteResolver"; +import { + createSegmentDecomposer, + SegmentDecomposer, +} from "../RouteResolver/resolveChain"; import type { BuilderLinkOptions } from "./BuilderLinkOptions"; import { BuilderLinkState } from "./BuilderLinkState"; import { HasBuilderLink } from "./HasBuilderLink"; @@ -21,7 +25,7 @@ export class BuilderLink * Registered current builder. */ currentBuilder?: HasBuilderLink = undefined; - resolveSegment?: SegmentResolver; + segmentDecomposer?: SegmentDecomposer; constructor(options: BuilderLinkOptions) { this.composer = options.composer; @@ -32,7 +36,7 @@ export class BuilderLink * Attach this link to a parent. */ attachToParent( - parentLink: BuilderLink, + parentLink: BuilderLink, segmentGetter: (match: unknown) => Segment ) { if (this.#state.state !== "unattached") { @@ -109,7 +113,7 @@ export class BuilderLink resolveSegment: SegmentResolver ): void { this.currentBuilder = builder; - this.resolveSegment = resolveSegment; + this.segmentDecomposer = createSegmentDecomposer(this, resolveSegment); } /** diff --git a/src/core/RouteResolver/resolveChain.ts b/src/core/RouteResolver/resolveChain.ts index 4ab9db5..1686d10 100644 --- a/src/core/RouteResolver/resolveChain.ts +++ b/src/core/RouteResolver/resolveChain.ts @@ -1,79 +1,112 @@ import type { BuilderLink } from "../BuilderLink"; +import { + ResolvedSegmentType, + SegmentResolver, +} from "../BuilderLink/SegmentResolver"; import type { Location } from "../Location"; import type { ResolvedRoute } from "./ResolvedRoute"; +type DecomposedSegmentType = ResolvedSegmentType< + ActionResult, + Segment, + Value +> & { + segment: Segment; + nextLocation: Location; +}; + +export type SegmentDecomposer = ( + location: Location +) => DecomposedSegmentType[]; +/** + * Create a segment decomposer function for given BuilderLink and SegmentResolver. + */ +export function createSegmentDecomposer( + link: BuilderLink, + resolveSegment: SegmentResolver +): SegmentDecomposer { + const { composer } = link; + return (location) => { + const decomposed = composer.decompose(location); + return decomposed.flatMap(({ segment, nextLocation }) => { + const resolved = resolveSegment(segment, nextLocation); + if (resolved === undefined) { + return []; + } + return [{ ...resolved, segment, nextLocation }]; + }); + }; +} + /** * Resolve location from given link and location * @package */ -export function resolveChain( - link: BuilderLink, +export function resolveChain( + link: BuilderLink, location: Location, currentLocation: Location ): Array> { - const decomposed = link.composer.decompose(location); - return decomposed.flatMap( - ({ segment, nextLocation: nextRemainingLocation }) => { - const resolved = link.resolveSegment?.(segment, nextRemainingLocation); - if (resolved === undefined) { - return []; - } - const nextCurrentLocation = link.composer.compose( - currentLocation, - segment - ); - const match = (resolved.type === "normal" - ? {} - : { - [resolved.matchKey]: segment, - }) as never; + const resolvedSegments = link.segmentDecomposer?.(location); + if (resolvedSegments === undefined) { + return []; + } + return resolvedSegments.flatMap((resolved) => { + const nextCurrentLocation = link.composer.compose( + currentLocation, + resolved.segment + ); + const match = (resolved.type === "normal" + ? {} + : { + [resolved.matchKey]: resolved.matchValue, + }) as never; - const childLink = resolved.link; + const childLink = resolved.link; - if (childLink === undefined) { - return [ - { - route: resolved.value, - match, - remainingLocation: nextRemainingLocation, - currentLocation: nextCurrentLocation, - }, - ]; - } + if (childLink === undefined) { + return [ + { + route: resolved.value, + match, + remainingLocation: resolved.nextLocation, + currentLocation: nextCurrentLocation, + }, + ]; + } - const result = resolveChain( - childLink, - nextRemainingLocation, - nextCurrentLocation - ); + const result = resolveChain( + childLink, + resolved.nextLocation, + nextCurrentLocation + ); - if ( - result.length === 0 && - childLink.composer.isLeaf(nextRemainingLocation) - ) { - return [ - { - route: resolved.value, - match, - remainingLocation: nextRemainingLocation, - currentLocation: nextCurrentLocation, - }, - ]; + if ( + result.length === 0 && + childLink.composer.isLeaf(resolved.nextLocation) + ) { + return [ + { + route: resolved.value, + match, + remainingLocation: resolved.nextLocation, + currentLocation: nextCurrentLocation, + }, + ]; + } + switch (resolved.type) { + case "normal": { + return result; } - switch (resolved.type) { - case "normal": { - return result; - } - case "matching": { - const key = resolved.matchKey; - const matchedValue = resolved.matchValue; - return result.map((res) => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (res.match as any)[key] = matchedValue; - return res; - }); - } + case "matching": { + const key = resolved.matchKey; + const matchedValue = resolved.matchValue; + return result.map((res) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (res.match as any)[key] = matchedValue; + return res; + }); } } - ); + }); }