Skip to content

Commit

Permalink
[state-router] Set "strict" in TS config and fix typings
Browse files Browse the repository at this point in the history
  • Loading branch information
mariuslundgard authored and rexxars committed Oct 6, 2020
1 parent 55ea871 commit 95b7fb7
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 26 deletions.
3 changes: 2 additions & 1 deletion packages/@sanity/state-router/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"compile": "tsc",
"compile:watch": "babel --watch --out-dir lib/ src/",
"benchmark": "npm run compile && node --prof --logfile=benchmarks.log perf/benchmark.js",
"clean": "rimraf lib"
"clean": "rimraf lib",
"type-check": "tsc --noEmit"
},
"keywords": [
"sanity",
Expand Down
7 changes: 5 additions & 2 deletions packages/@sanity/state-router/src/components/IntentLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ interface IntentLinkProps {
export default class IntentLink extends React.PureComponent<
IntentLinkProps & Omit<React.HTMLProps<HTMLAnchorElement>, 'ref'>
> {
context: RouterProviderContext
context: RouterProviderContext | null = null

static contextTypes = {
__internalRouter: internalRouterContextTypeCheck
}

_element: Link
_element: Link | null = null

focus() {
if (this._element) {
Expand All @@ -32,9 +32,12 @@ export default class IntentLink extends React.PureComponent<
}

resolveIntentLink(intent: string, params?: IntentParameters) {
if (!this.context) throw new Error('IntentLink: missing context value')

if (!this.context.__internalRouter) {
return `javascript://intent@${JSON.stringify({intent, params})}`
}

return this.context.__internalRouter.resolveIntentLink(intent, params)
}

Expand Down
8 changes: 6 additions & 2 deletions packages/@sanity/state-router/src/components/Link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ interface LinkProps {
export default class Link extends React.PureComponent<
LinkProps & Omit<React.HTMLProps<HTMLAnchorElement>, 'ref'>
> {
context: RouterProviderContext
_element: HTMLAnchorElement
context: RouterProviderContext | null = null
_element: HTMLAnchorElement | null = null

static defaultProps = {
replace: false
Expand All @@ -30,6 +30,8 @@ export default class Link extends React.PureComponent<
}

private handleClick = (event: React.MouseEvent<HTMLAnchorElement>): void => {
if (!this.context) throw new Error('Link: missing context value')

if (!this.context.__internalRouter) {
return
}
Expand All @@ -40,6 +42,8 @@ export default class Link extends React.PureComponent<

const {onClick, href, target, replace} = this.props

if (!href) return

if (onClick) {
onClick(event)
}
Expand Down
20 changes: 14 additions & 6 deletions packages/@sanity/state-router/src/components/RouteScope.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ import PropTypes from 'prop-types'
import React from 'react'
import isEmpty from '../utils/isEmpty'

import {InternalRouter, NavigateOptions, RouterProviderContext} from './types'
import {RouterContext} from '../RouterContext'
import {InternalRouter, NavigateOptions, RouterProviderContext} from './types'

function addScope(routerState: Object, scope: string, scopedState: Object) {
function addScope(
routerState: Record<string, any>,
scope: string,
scopedState: Record<string, any>
) {
return (
scopedState && {
...routerState,
Expand All @@ -20,7 +24,7 @@ type Props = {
}

export default class RouteScope extends React.Component<Props> {
context: RouterProviderContext
context: RouterProviderContext | null = null
__internalRouter: InternalRouter

static childContextTypes = {
Expand Down Expand Up @@ -51,22 +55,26 @@ export default class RouteScope extends React.Component<Props> {

getScopedState = () => {
const {scope} = this.props
if (!this.context) throw new Error('RouteScope: missing context value')
const parentInternalRouter = this.context.__internalRouter
return parentInternalRouter.getState()[scope]
}

resolvePathFromState = (nextState: Object): string => {
resolvePathFromState = (nextState: Record<string, any>): string => {
if (!this.context) throw new Error('RouteScope: missing context value')

const parentInternalRouter = this.context.__internalRouter
const scope = this.props.scope

const nextStateScoped: Object = isEmpty(nextState)
const nextStateScoped: Record<string, any> = isEmpty(nextState)
? {}
: addScope(parentInternalRouter.getState(), scope, nextState)

return parentInternalRouter.resolvePathFromState(nextStateScoped)
}

navigate = (nextState: Object, options?: NavigateOptions): void => {
navigate = (nextState: Record<string, any>, options?: NavigateOptions): void => {
if (!this.context) throw new Error('RouteScope: missing context value')
const parentInternalRouter = this.context.__internalRouter
const nextScopedState = addScope(parentInternalRouter.getState(), this.props.scope, nextState)
parentInternalRouter.navigate(nextScopedState, options)
Expand Down
9 changes: 6 additions & 3 deletions packages/@sanity/state-router/src/components/StateLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ type Props = {
}

export default class StateLink extends React.PureComponent<Props> {
context: RouterProviderContext
_element: Link
context: RouterProviderContext | null = null
_element: Link | null = null

static defaultProps = {
replace: false,
Expand Down Expand Up @@ -44,10 +44,13 @@ export default class StateLink extends React.PureComponent<Props> {
return this.resolvePathFromState(nextState)
}

resolvePathFromState(state: Object) {
resolvePathFromState(state: Record<string, any>) {
if (!this.context) throw new Error('StateLink: missing context value')

if (!this.context.__internalRouter) {
return `javascript://state@${JSON.stringify(state)}`
}

return this.context.__internalRouter.resolvePathFromState(state)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import withRouterHOC from './withRouterHOC'
import {Router} from './types'

type Props = {
router?: Router
router: Router
children: (router: Router) => React.ReactElement
}

Expand Down
16 changes: 11 additions & 5 deletions packages/@sanity/state-router/src/components/withRouterHOC.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react'
import React, {ComponentType} from 'react'
import internalRouterContextTypeCheck from './internalRouterContextTypeCheck'
import {Router, InternalRouter} from './types'
import {ComponentType} from 'react'

const NO_CONTEXT_STATE = {
state: {},
Expand All @@ -22,28 +21,33 @@ export default function withRouterHOC<OuterProps>(
) {
return class WithRouter extends React.Component<OuterProps> {
static displayName = `withRouter(${Component.displayName || Component.name})`
unsubscribe: () => void
unsubscribe: (() => void) | null = null

state = {
routerState: {}
}

context: {
__internalRouter?: InternalRouter
}
} | null = null

static contextTypes = {
__internalRouter: internalRouterContextTypeCheck
}

constructor(props, context) {
super(props)

const __internalRouter = context.__internalRouter

if (__internalRouter) {
this.state = {routerState: __internalRouter.getState()}
}
}

UNSAFE_componentWillMount() {
if (!this.context) throw new Error('WithRouter: missing context value')

const __internalRouter = this.context.__internalRouter
if (!__internalRouter) {
return
Expand All @@ -54,10 +58,12 @@ export default function withRouterHOC<OuterProps>(
}

componentWillUnmount() {
this.unsubscribe()
if (this.unsubscribe) this.unsubscribe()
}

render() {
if (!this.context) throw new Error('WithRouter: missing context value')

const internalRouter = this.context.__internalRouter

const router: Router = internalRouter
Expand Down
4 changes: 2 additions & 2 deletions packages/@sanity/state-router/src/parseRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ function createSegment(segment: string): Segment | null {
export default function parseRoute(route: string): Route {
const [pathname] = route.split('?')

const segments: Segment[] = pathname
const segments = pathname
.split('/')
.map(createSegment)
.filter(Boolean)
.filter(Boolean) as Segment[]

return {
raw: route,
Expand Down
8 changes: 5 additions & 3 deletions packages/@sanity/state-router/src/resolveStateFromPath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ function matchPath(
}

const rest = parts.slice(segmentsLength)
let childState = null
let childState: {
[key: string]: string
} | null = null
const children =
typeof node.children === 'function' ? arrayify(node.children(state)) : node.children
children.some(childNode => {
Expand All @@ -44,11 +46,11 @@ function matchPath(
return null
}

const mergedState = {...state, ...childState}
const mergedState = {...state, ...(childState || {})}
return node.scope ? {[node.scope]: mergedState} : mergedState
}

export default function resolveStateFromPath(node: Node, path: string): Object | null {
export default function resolveStateFromPath(node: Node, path: string): Record<string, any> | null {
debug('resolving state from path %s', path)

const pathMatch = matchPath(node, path.split('?')[0])
Expand Down
1 change: 0 additions & 1 deletion packages/@sanity/state-router/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"exclude": ["node_modules", "test/**/*.ts"],
"compilerOptions": {
"declaration": true,
"strict": false,
"jsx": "react",
"outDir": "./lib"
}
Expand Down

0 comments on commit 95b7fb7

Please sign in to comment.