Skip to content

Commit 3e9fbab

Browse files
committed
feat: improved types for TypeScript
1 parent 1b7ce57 commit 3e9fbab

22 files changed

+1245
-230
lines changed

.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
dist/__tests__

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"test": "jest",
1919
"test:dev": "jest --watch --no-coverage",
2020
"test:coverage:watch": "jest --watch",
21-
"test:ts": "tsc --noEmit",
21+
"test:ts": "tsc -p types/__tests__/tsconfig.json",
2222
"postinstall": "node -e \"console.log('\\u001b[35m\\u001b[1mEnjoy react-spring? You can now donate to our open collective:\\u001b[22m\\u001b[39m\\n > \\u001b[34mhttps://opencollective.com/react-spring/donate\\u001b[0m')\""
2323
},
2424
"husky": {
@@ -97,6 +97,7 @@
9797
"rollup-plugin-node-resolve": "4.0.0",
9898
"rollup-plugin-size-snapshot": "0.8.0",
9999
"rollup-plugin-uglify": "6.0.2",
100+
"spec.ts": "^1.1.0",
100101
"typescript": "3.3.3"
101102
},
102103
"peerDependencies": {

tsconfig.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
"include": ["src", "types"],
23
"compilerOptions": {
34
"target": "es2017",
45
"moduleResolution": "node",
@@ -15,6 +16,5 @@
1516
"noUnusedLocals": true,
1617
"noUnusedParameters": true,
1718
"strict": true
18-
},
19-
"include": ["src/**/*", "types/**/*.ts"]
19+
}
2020
}

types/__tests__/.prettierrc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"semi": true,
3+
"trailingComma": "es5",
4+
"singleQuote": true,
5+
"jsxBracketSameLine": true,
6+
"tabWidth": 2,
7+
"printWidth": 80
8+
}

types/__tests__/Spring.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { assert, test, _ } from 'spec.ts';
2+
import { Spring, animated, AnimatedValue } from '../web';
3+
import React from 'react';
4+
5+
const View = animated('div');
6+
7+
test('basic usage', () => {
8+
<Spring
9+
from={{ opacity: 0 }}
10+
to={{ opacity: 1, color: 'blue' }}
11+
onRest={values => {
12+
assert(values, _ as {
13+
[key: string]: unknown;
14+
// FIXME: should include "opacity" and "color"
15+
});
16+
}}>
17+
{props => {
18+
assert(props, _ as {
19+
[key: string]: AnimatedValue<any>;
20+
// FIXME: should include "opacity" and "color"
21+
});
22+
return <View style={props} />;
23+
}}
24+
</Spring>;
25+
});

types/__tests__/Trail.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { assert, test, _ } from 'spec.ts';
2+
import { Trail, animated, AnimatedValue } from '../web';
3+
import React from 'react';
4+
5+
const View = animated('div');
6+
7+
const items = [1, 2] as [1, 2];
8+
9+
test('basic usage', () => {
10+
<Trail items={items} from={{ opacity: 0 }} to={{ opacity: 1, color: 'blue' }}>
11+
{item => props => {
12+
assert(item, _ as 1 | 2);
13+
assert(props, _ as {
14+
[key: string]: AnimatedValue<any>;
15+
opacity: AnimatedValue<number>;
16+
color: AnimatedValue<string>;
17+
});
18+
return <View style={props}>{item}</View>;
19+
}}
20+
</Trail>;
21+
});

types/__tests__/Transition.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { assert, test, _ } from 'spec.ts';
2+
import { Transition, animated, AnimatedValue, TransitionPhase } from '../web';
3+
import React from 'react';
4+
5+
const View = animated('div');
6+
7+
const items = [1, 2] as [1, 2];
8+
9+
test('basic usage', () => {
10+
<Transition
11+
items={items}
12+
enter={{ opacity: 1, color: 'blue' }}
13+
leave={{ opacity: 0 }}>
14+
{(item, phase, i) => props => {
15+
assert(props, _ as {
16+
[key: string]: AnimatedValue<any>;
17+
opacity: AnimatedValue<number>;
18+
color: AnimatedValue<string>;
19+
});
20+
assert(item, _ as 1 | 2);
21+
assert(phase, _ as TransitionPhase);
22+
assert(i, _ as number);
23+
return <View style={props}>{item}</View>;
24+
}}
25+
</Transition>;
26+
});

types/__tests__/common.ts

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
import {
2+
PickAnimated,
3+
ForwardProps,
4+
AnimatedProps,
5+
AnimatedValue,
6+
AnimationFrame,
7+
UnknownProps,
8+
Remap,
9+
} from '../lib/common';
10+
import { assert, _, test } from 'spec.ts';
11+
12+
const $1: 1 = 1;
13+
14+
const reservedProps = {
15+
config: $1,
16+
from: {},
17+
to: {},
18+
ref: $1,
19+
reset: $1,
20+
reverse: $1,
21+
immediate: $1,
22+
delay: $1,
23+
lazy: $1,
24+
onStart: $1,
25+
onRest: $1,
26+
onFrame: $1,
27+
};
28+
29+
const forwardProps = {
30+
foo: $1,
31+
bar: $1,
32+
};
33+
34+
type R = typeof reservedProps;
35+
type F = typeof forwardProps;
36+
37+
test('ForwardProps', () => {
38+
// With reserved props, no forward props
39+
type P1 = ForwardProps<R>;
40+
assert(_ as P1, _ as {});
41+
42+
// With reserved and forward props
43+
type P2 = ForwardProps<R & F>;
44+
assert(_ as P2, _ as F);
45+
46+
// With forward props, no reserved props
47+
type P3 = ForwardProps<F>;
48+
assert(_ as P3, _ as F);
49+
50+
// No reserved or forward props
51+
type P4 = ForwardProps<{}>;
52+
assert(_ as P4, _ as {});
53+
});
54+
55+
test('PickAnimated', () => {
56+
// No props
57+
type A1 = PickAnimated<{}>;
58+
assert(_ as A1, _ as {});
59+
60+
// Forward props only
61+
type A3 = PickAnimated<F>;
62+
assert(_ as A3, _ as F);
63+
64+
// Forward props and "from" prop
65+
type A4 = PickAnimated<{
66+
foo: 1;
67+
width: 1;
68+
from: { bar: 1; width: 2 };
69+
}>;
70+
assert(_ as A4, _ as Remap<F & { width: 1 | 2 }>);
71+
72+
// "to" and "from" props
73+
type A5 = PickAnimated<{
74+
to: { foo: 1; width: 1 };
75+
from: { bar: 1; width: 2 };
76+
}>;
77+
assert(_ as A5, _ as Remap<F & { width: 1 | 2 }>);
78+
79+
// "useTransition" props
80+
type A6 = PickAnimated<{
81+
from: { a: 1 };
82+
initial: { b: 1 };
83+
enter: { c: 1 };
84+
update: { d: 1 };
85+
leave: { e: 1 };
86+
}>;
87+
assert(
88+
_ as A6,
89+
_ as {
90+
a: 1;
91+
b: 1;
92+
c: 1;
93+
d: 1;
94+
e: 1;
95+
}
96+
);
97+
98+
// Same keys in each phase
99+
type A7 = PickAnimated<{
100+
from: { a: 1 };
101+
enter: { a: 2 };
102+
leave: { a: 3 };
103+
update: { a: 4 };
104+
initial: { a: 5 };
105+
}>;
106+
assert(
107+
_ as A7,
108+
_ as {
109+
a: 1 | 2 | 3 | 4 | 5;
110+
}
111+
);
112+
});
113+
114+
test('AnimatedProps', () => {
115+
// Primitive props
116+
type P2 = AnimatedProps<{ foo?: number }>;
117+
assert(
118+
_ as P2,
119+
_ as {
120+
foo?: number | AnimatedValue<number>;
121+
}
122+
);
123+
124+
// Object props
125+
type P3 = AnimatedProps<{ foo?: { bar?: number } }>;
126+
assert(
127+
_ as P3,
128+
_ as {
129+
foo?: AnimatedProps<{ bar?: number }>;
130+
}
131+
);
132+
133+
// Array props
134+
type P4 = AnimatedProps<{ foo: [number, number] }>;
135+
assert(
136+
_ as P4,
137+
_ as {
138+
foo: [number, number] | AnimatedValue<[number, number]>;
139+
}
140+
);
141+
142+
// Atomic object props
143+
type P5 = AnimatedProps<{
144+
set: Set<any>;
145+
map: Map<any, any>;
146+
date: Date;
147+
func: Function;
148+
prom: Promise<any>;
149+
}>;
150+
assert(
151+
_ as P5,
152+
_ as {
153+
set: Set<any> | AnimatedValue<Set<any>>;
154+
map: Map<any, any> | AnimatedValue<Map<any, any>>;
155+
date: Date | AnimatedValue<Date>;
156+
func: Function | AnimatedValue<Function>;
157+
prom: Promise<any> | AnimatedValue<Promise<any>>;
158+
}
159+
);
160+
});
161+
162+
test('SpringFrame', () => {
163+
type T1 = AnimationFrame<{}>;
164+
assert(_ as T1, _ as UnknownProps);
165+
166+
type T2 = AnimationFrame<{ to: { a: number }; from: { b: number } }>;
167+
assert(_ as T2, _ as { [key: string]: unknown; a: number; b: number });
168+
});

types/__tests__/tsconfig.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"include": ["*.ts", "useChain.tsx"],
3+
"compilerOptions": {
4+
"target": "es2017",
5+
"moduleResolution": "node",
6+
"lib": ["dom", "es2017"],
7+
"noEmit": true,
8+
"jsx": "react",
9+
"allowSyntheticDefaultImports": true,
10+
"noUnusedLocals": true,
11+
"noUnusedParameters": true,
12+
"strict": true
13+
}
14+
}

types/__tests__/useChain.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { test } from 'spec.ts';
2+
import { useChain, SpringHandle } from '../web';
3+
import { RefObject } from 'react';
4+
5+
const refs: RefObject<SpringHandle>[] = [];
6+
7+
test('basic usage', () => {
8+
// No timesteps
9+
useChain(refs);
10+
11+
// With timesteps
12+
useChain(refs, [0, 1]);
13+
14+
// Cut timesteps in half
15+
useChain(refs, [0, 1], 1000 / 2);
16+
});

0 commit comments

Comments
 (0)