Skip to content

Commit cc59fb9

Browse files
committed
feat: add typescript definitions
fixes #197
1 parent 07564e3 commit cc59fb9

File tree

9 files changed

+321
-7
lines changed

9 files changed

+321
-7
lines changed

.circleci/config.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,15 @@ jobs:
3030
- persist_to_workspace:
3131
root: .
3232
paths: .
33-
lint-and-flow:
33+
lint-and-typecheck:
3434
<<: *defaults
3535
steps:
3636
- attach_workspace:
3737
at: ~/linaria
3838
- run: |
3939
yarn lint
4040
yarn flow
41+
yarn typescript
4142
unit-tests:
4243
<<: *defaults
4344
steps:
@@ -74,7 +75,7 @@ workflows:
7475
build-and-test:
7576
jobs:
7677
- install-dependencies
77-
- lint-and-flow:
78+
- lint-and-typecheck:
7879
requires:
7980
- install-dependencies
8081
- unit-tests:

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
"version": "1.0.0-alpha.13",
44
"description": "Blazing fast zero-runtime CSS in JS library",
55
"main": "lib/index.js",
6+
"types": "types/index.d.ts",
67
"files": [
78
"lib/",
9+
"types/",
810
"react.js",
911
"server.js",
1012
"babel.js",
@@ -29,6 +31,7 @@
2931
"scripts": {
3032
"lint": "eslint .",
3133
"flow": "flow",
34+
"typescript": "dtslint types",
3235
"test": "jest",
3336
"test:unit": "jest __tests__",
3437
"test:integration": "jest __integration-tests__",
@@ -50,12 +53,14 @@
5053
"@babel/preset-flow": "^7.0.0",
5154
"@babel/preset-react": "^7.0.0",
5255
"@callstack/eslint-config": "^2.0.0",
56+
"@types/react": "^16.4.18",
5357
"all-contributors-cli": "^5.4.0",
5458
"babel-core": "^7.0.0-bridge.0",
5559
"codecov": "^3.1.0",
5660
"conventional-changelog-cli": "^2.0.5",
5761
"dedent": "^0.7.0",
5862
"del-cli": "^1.1.0",
63+
"dtslint": "^0.3.0",
5964
"eslint": "^5.4.0",
6065
"flow-bin": "^0.79.1",
6166
"flow-copy-source": "^2.0.2",

src/react/styled.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,9 @@ type StyledComponent<T> = React.ComponentType<T & { as?: React$ElementType }>;
8282
8383
type StyledTag<T> = (strings: string[], ...exprs: Array<string | number | {} | (T => string | number)>) => StyledComponent<T>;
8484
85-
declare module.exports: {|
85+
type StyledJSXIntrinsics = $ObjMap<$JSXIntrinsics, <T>({ props: T }) => StyledTag<T>>;
86+
87+
declare module.exports: StyledJSXIntrinsics & {|
8688
<T>(T): StyledTag<React.ElementConfig<T>>,
87-
[string]: StyledTag<{ children?: React.Node, [key: string]: any }>,
8889
|};
8990
*/

types/index.d.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// TypeScript Version: 2.8
2+
3+
declare module 'linaria' {
4+
function css(
5+
strings: TemplateStringsArray,
6+
...exprs: Array<string | number | object>
7+
): string;
8+
9+
function cx(
10+
...classNames: Array<string | false | undefined | null | 0>
11+
): string;
12+
}
13+
14+
declare module 'linaria/react' {
15+
import * as React from 'react';
16+
17+
type InterpolationFunction<T> = (props: T) => string | number;
18+
19+
type StyledComponent<T> = React.StatelessComponent<
20+
T & { as?: React.ReactType }
21+
>;
22+
23+
type StyledTag<T> = (
24+
strings: TemplateStringsArray,
25+
...exprs: Array<string | number | object | InterpolationFunction<T>>
26+
) => StyledComponent<T>;
27+
28+
type StyledJSXIntrinsics = {
29+
[P in keyof JSX.IntrinsicElements]: StyledTag<
30+
JSX.IntrinsicElements[P] & { [key: string]: any }
31+
>
32+
};
33+
34+
const styled: StyledJSXIntrinsics & {
35+
<T>(component: React.ReactType<T>): StyledTag<T>;
36+
37+
[key: string]: StyledTag<{
38+
children?: React.ReactNode;
39+
[key: string]: any;
40+
}>;
41+
};
42+
}
43+
44+
declare module 'linaria/server' {
45+
function collect(
46+
html: string,
47+
css: string
48+
): { critical: string; other: string };
49+
}

types/tests/index.tsx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { css, cx } from 'linaria';
2+
3+
const tomato = 'tomato';
4+
const border = 1;
5+
6+
const absoluteFill = {
7+
position: 'absolute',
8+
top: 0,
9+
left: 0,
10+
bottom: 0,
11+
right: 0,
12+
};
13+
14+
// $ExpectType string
15+
css`
16+
color: ${tomato};
17+
border-width: ${border}px;
18+
19+
&.abs {
20+
${absoluteFill};
21+
}
22+
`;
23+
24+
// $ExpectType string
25+
css`font-family: sans-serif`;
26+
27+
// $ExpectError
28+
css`color: ${true}`;
29+
30+
// $ExpectError
31+
css`color: ${undefined}`;
32+
33+
// $ExpectError
34+
css`color: ${null}`;
35+
36+
// $ExpectType string
37+
cx('test', false, undefined, null, 0);
38+
39+
// $ExpectError
40+
cx('test', 42);
41+
42+
// $ExpectError
43+
cx('test', true);
44+
45+
// $ExpectError
46+
cx('test', {});

types/tests/react.tsx

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import * as React from 'react';
2+
import { styled } from 'linaria/react';
3+
4+
const white = 'white';
5+
const tomato = 'tomato';
6+
const border = 1;
7+
8+
const absoluteFill = {
9+
position: 'absolute',
10+
top: 0,
11+
left: 0,
12+
bottom: 0,
13+
right: 0,
14+
};
15+
16+
const Button = styled.button`
17+
color: ${white};
18+
background-color: ${props => props.background};
19+
border-width: ${border}px;
20+
21+
&.abs {
22+
${absoluteFill};
23+
}
24+
`;
25+
26+
const CustomButton = styled(Button)`
27+
&:hover {
28+
background-color: ${tomato};
29+
}
30+
`;
31+
32+
class Title extends React.Component<{ label: string; className?: string }> {
33+
render() {
34+
return <h1 className={this.props.className}>{this.props.label}</h1>;
35+
}
36+
}
37+
38+
const CustomTitle = styled(Title)`
39+
font-family: sans-serif;
40+
`;
41+
42+
// $Expect Element
43+
<Button as="a">Hello world</Button>;
44+
45+
// $ExpectError
46+
<Button onClick={42}>Hello world</Button>;
47+
48+
// $Expect Element
49+
<CustomButton onClick={() => alert('Clicked')}>Hello world</CustomButton>;
50+
51+
// $Expect Element
52+
<CustomTitle label="Hello world" />;
53+
54+
// $Expect Element
55+
<CustomTitle label="Hello world" className="primary" />;
56+
57+
// $ExpectError
58+
<CustomTitle />;

types/tests/server.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { collect } from 'linaria/server';
2+
3+
// $ExpectType { critical: string; other: string; }
4+
collect(
5+
'<div class="foo">Hello</div>',
6+
'.foo { color: blue; }'
7+
);

types/tsconfig.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"compilerOptions": {
3+
"module": "commonjs",
4+
"lib": ["es6", "dom"],
5+
"noImplicitAny": true,
6+
"noImplicitThis": true,
7+
"strictNullChecks": true,
8+
"strictFunctionTypes": true,
9+
"noEmit": true,
10+
"forceConsistentCasingInFileNames": true,
11+
"jsx": "react"
12+
}
13+
}

0 commit comments

Comments
 (0)