Skip to content

Commit edca2de

Browse files
authored
Merge pull request #1055 from primer/VanAnderson/utils-ts-migration
Migrate utils to TypeScript
2 parents 82b34ea + b7904f6 commit edca2de

File tree

8 files changed

+38
-24
lines changed

8 files changed

+38
-24
lines changed

.changeset/light-ears-run.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@primer/components": patch
3+
---
4+
5+
Migrate `utils` to TypeScript
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
declare module 'jest-styled-components/serializer'

jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ module.exports = {
22
cacheDirectory: '.test',
33
collectCoverage: true,
44
collectCoverageFrom: ['src/*.js'],
5-
setupFilesAfterEnv: ['<rootDir>/src/utils/test-matchers.js', '<rootDir>/src/utils/test-deprecations.js']
5+
setupFilesAfterEnv: ['<rootDir>/src/utils/test-matchers.tsx', '<rootDir>/src/utils/test-deprecations.tsx']
66
}

src/utils/deprecate.js renamed to src/utils/deprecate.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
/* eslint-disable no-console */
22
import {useRef, useCallback} from 'react'
3+
declare var __DEV__: boolean
4+
5+
type DeprecationType = {name: string; message: string; version: string}
36

47
const noop = () => {}
58
// eslint-disable-next-line import/no-mutable-exports
6-
let deprecate = null
9+
let deprecate: ({name, message, version}: DeprecationType) => void | (() => void) = noop
710

811
if (__DEV__) {
9-
deprecate = ({name, message, version}) => {
12+
deprecate = ({name, message, version}: DeprecationType) => {
1013
Deprecations.deprecate({name, message, version})
1114
}
12-
} else {
13-
deprecate = noop
1415
}
1516

1617
export {deprecate}
@@ -19,7 +20,7 @@ export {deprecate}
1920
let useDeprecation = null
2021

2122
if (__DEV__) {
22-
useDeprecation = ({name, message, version}) => {
23+
useDeprecation = ({name, message, version}: DeprecationType) => {
2324
const ref = useRef(false)
2425
const logDeprecation = useCallback(() => {
2526
if (!ref.current) {
@@ -39,6 +40,9 @@ if (__DEV__) {
3940
export {useDeprecation}
4041

4142
export class Deprecations {
43+
static instance: Deprecations | null = null
44+
deprecations: Array<DeprecationType>
45+
4246
static get() {
4347
if (!Deprecations.instance) {
4448
Deprecations.instance = new Deprecations()
@@ -51,7 +55,7 @@ export class Deprecations {
5155
this.deprecations = []
5256
}
5357

54-
static deprecate({name, message, version}) {
58+
static deprecate({name, message, version}: DeprecationType) {
5559
const msg = `WARNING! ${name} is deprecated and will be removed in version ${version}. ${message}`
5660
console.warn(msg)
5761

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
export default function isNumeric(n) {
1+
export default function isNumeric(n: any) {
22
return !isNaN(parseFloat(n)) && isFinite(n)
33
}

src/utils/test-deprecations.js renamed to src/utils/test-deprecations.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import semver from 'semver'
2-
import {Deprecations} from '../utils/deprecate'
2+
import {Deprecations} from './deprecate'
33

44
const ourVersion = require('../../package.json').version
55

src/utils/test-matchers.js renamed to src/utils/test-matchers.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ import React from 'react'
22
import 'jest-styled-components'
33
import {styleSheetSerializer} from 'jest-styled-components/serializer'
44
import theme from '../theme'
5+
import {ReactTestRendererJSON, ReactTestRendererNode} from 'react-test-renderer'
56
import {getClasses, mount, getComputedStyles, render} from './testing'
7+
import {Nullish} from '@testing-library/react'
68

79
expect.addSnapshotSerializer(styleSheetSerializer)
810

9-
const stringify = d => JSON.stringify(d, null, ' ')
11+
const stringify = (d: object) => JSON.stringify(d, null, ' ')
1012

1113
/**
1214
* These are props that styled-system aliases for backwards compatibility.
@@ -34,7 +36,9 @@ expect.extend({
3436

3537
toHaveClasses(node, klasses, only = false) {
3638
const classes = getClasses(node)
37-
const pass = only ? this.equals(classes.sort(), klasses.sort()) : klasses.every(klass => classes.includes(klass))
39+
const pass = only
40+
? this.equals(classes.sort(), klasses.sort())
41+
: klasses.every((klass: Array<string>) => classes.includes(klass))
3842
return {
3943
pass,
4044
message: () => `expected ${stringify(classes)} to include: ${stringify(klasses)}`
@@ -69,13 +73,14 @@ expect.extend({
6973
const elem = React.cloneElement(element, {sx: sxPropValue})
7074
const rendered = render(elem)
7175

72-
function checkStylesDeep(rendered) {
73-
const className = rendered.props ? rendered.props.className : ''
76+
function checkStylesDeep(rendered: ReactTestRendererJSON): boolean {
77+
const className = rendered?.props ? rendered.props.className : ''
7478
const styles = getComputedStyles(className)
75-
if (styles[mediaKey] && styles[mediaKey].color) {
79+
const mediaStyles = styles[mediaKey] as Nullish<Record<string, string>>
80+
if (mediaStyles && mediaStyles.color) {
7681
return true
7782
} else if (rendered.children) {
78-
return rendered.children.some(child => checkStylesDeep(child))
83+
return rendered.children.some((child: ReactTestRendererNode) => checkStylesDeep(child as ReactTestRendererJSON))
7984
} else {
8085
return false
8186
}

src/utils/testing.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export function renderClasses(component: React.ReactElement): string {
7373
/**
7474
* Returns true if a node renders with a single class.
7575
*/
76-
export function rendersClass(node: React.ReactElement, klass: string): boolean {
76+
export function rendersClass(node: React.ReactElement, klass: string): boolean {
7777
return renderClasses(node).includes(klass)
7878
}
7979

@@ -96,7 +96,7 @@ export function renderStyles(node: React.ReactElement): any {
9696
return getComputedStyles(className)
9797
}
9898

99-
export function getComputedStyles(className: string): Record<string, string> {
99+
export function getComputedStyles(className: string): Record<string, string | Record<string, string>> {
100100
const div = document.createElement('div')
101101
div.className = className
102102

@@ -107,14 +107,14 @@ export function getComputedStyles(className: string): Record<string, string> {
107107
if (rule instanceof CSSMediaRule) {
108108
readMedia(rule)
109109
} else if (rule instanceof CSSStyleRule) {
110-
readRule(rule, computed)
111-
} else {
110+
readRule(rule, computed)
111+
} else {
112112
// console.warn('rule.type =', rule.type)
113113
}
114114
}
115115
}
116116

117-
return computed
117+
return computed
118118

119119
function matchesSafe(node: HTMLDivElement, selector: string) {
120120
if (!selector) {
@@ -194,16 +194,15 @@ export function unloadCSS(path: string) {
194194
// to render without errors, you can pass a `toRender` function that
195195
// returns an element ready to be rendered.
196196

197-
198197
interface Options {
199198
skipAs?: boolean
200199
skipSx?: boolean
201200
}
202201

203202
interface BehavesAsComponent {
204-
Component: React.FunctionComponent<any>,
205-
systemPropArray: any[],
206-
toRender?: () => React.ReactElement,
203+
Component: React.ComponentType<any>
204+
systemPropArray: any[]
205+
toRender?: () => React.ReactElement
207206
options?: Options
208207
}
209208

0 commit comments

Comments
 (0)