我有一个简单的 react-native 样板,我正在尝试测试一个用 typescript 编写的简单的 react-native 组件:
// Splash.tsx
import React, { Component } from 'react';
import { SContainer, STitle, SSubtitle, SPara } from './Splash.style';
export default class Splash extends Component {
render() {
return (
<SContainer>
<STitle>Clean Slate</STitle>
<SSubtitle>A react-native boilerplate</SSubtitle>
<SPara>
with TypeScript, React-Navigation, {'\n'}styled-components, Redux and
Sagas
</SPara>
</SContainer>
);
}
}
SContainer
, STitle
, SSubtitle
&SPara
是styled-components
我有这个测试:
// Splash.spec.tsx
import React from 'react';
import Splash from './Splash';
import renderer from 'react-test-renderer';
test('renders correctly', () => {
const tree = renderer.create(<Splash onAppStart={() => {}} />).toJSON();
expect(tree).toMatchSnapshot();
});
我还有其他纯 JS/TS 函数(没有 JSX)的笑话测试,测试运行并完美通过。但是当我jest -- -u
在 Splash.spec.tsx 上运行时,我得到了这个:
FAIL src/screens/Splash/Splash.spec.tsx
● Test suite failed to run
TypeScript diagnostics (customize using `[jest-config].globals.ts-jest.diagnostics` option):
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:18:1 - error TS8002: 'import ... =' can only be used in a .ts file.
18 import type {
~~~~~~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:41:13 - error TS8008: 'type aliases' can only be used in a .ts file.
41 export type ViewStyleProp = ____ViewStyleProp_Internal;
~~~~~~~~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:51:13 - error TS8008: 'type aliases' can only be used in a .ts file.
51 export type TextStyleProp = ____TextStyleProp_Internal;
~~~~~~~~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:61:13 - error TS8008: 'type aliases' can only be used in a .ts file.
61 export type ImageStyleProp = ____ImageStyleProp_Internal;
~~~~~~~~~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:70:13 - error TS8008: 'type aliases' can only be used in a .ts file.
70 export type DangerouslyImpreciseStyleProp = ____DangerouslyImpreciseStyleProp_Internal;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:88:13 - error TS8008: 'type aliases' can only be used in a .ts file.
88 export type TypeForStyleKey<
~~~~~~~~~~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:90:18 - error TS8011: 'type arguments' can only be used in a .ts file.
90 > = $ElementType<____DangerouslyImpreciseStyle_Internal, key>;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:107:13 - error TS8008: 'type aliases' can only be used in a .ts file.
107 export type ViewStyle = ____ViewStyle_Internal;
~~~~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:124:13 - error TS8008: 'type aliases' can only be used in a .ts file.
124 export type TextStyle = ____TextStyle_Internal;
~~~~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:141:13 - error TS8008: 'type aliases' can only be used in a .ts file.
141 export type ImageStyle = ____ImageStyle_Internal;
~~~~~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:155:13 - error TS8008: 'type aliases' can only be used in a .ts file.
155 export type DangerouslyImpreciseStyle = ____DangerouslyImpreciseStyle_Internal;
~~~~~~~~~~~~~~~~~~~~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:162:13 - error TS8008: 'type aliases' can only be used in a .ts file.
162 export type LayoutStyle = ____LayoutStyle_Internal;
~~~~~~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:163:13 - error TS8008: 'type aliases' can only be used in a .ts file.
163 export type ShadowStyle = ____ShadowStyle_Internal;
~~~~~~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:164:13 - error TS8008: 'type aliases' can only be used in a .ts file.
164 export type TransformStyle = ____TransformStyle_Internal;
~~~~~~~~~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:171:21 - error TS8010: 'types' can only be used in a .ts file.
171 const absoluteFill: LayoutStyle = {
~~~~~~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:253:32 - error TS8010: 'types' can only be used in a .ts file.
253 absoluteFill: (absoluteFill: any), // TODO: This should be updated after we fix downstream Flow sites.
~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:275:11 - error TS8004: 'type parameter declarations' can only be used in a .ts file.
275 compose<T: DangerouslyImpreciseStyleProp>(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:276:13 - error TS8010: 'types' can only be used in a .ts file.
276 style1: ?T,
~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:277:13 - error TS8010: 'types' can only be used in a .ts file.
277 style2: ?T,
~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:278:6 - error TS8010: 'types' can only be used in a .ts file.
278 ): ?T | $ReadOnlyArray<T> {
~~~~~~~~~~~~~~~~~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:280:48 - error TS8011: 'type arguments' can only be used in a .ts file.
280 return ([style1, style2]: $ReadOnlyArray<T>);
~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:337:15 - error TS8010: 'types' can only be used in a .ts file.
337 property: string,
~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:338:14 - error TS8010: 'types' can only be used in a .ts file.
338 process: (nextProp: mixed) => mixed,
~~~~~~~~~~~~~~~~~~~~~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:361:10 - error TS8004: 'type parameter declarations' can only be used in a .ts file.
361 create<+S: ____Styles_Internal>(obj: S): $ObjMap<S, (Object) => any> {
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:18:13 - error TS1005: '=' expected.
18 import type {
~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:31:1 - error TS1109: Expression expected.
31 } from 'StyleSheetTypes';
~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:31:8 - error TS1005: ';' expected.
31 } from 'StyleSheetTypes';
~~~~~~~~~~~~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:89:3 - error TS1139: Type parameter declaration expected.
89 +key: $Keys<____DangerouslyImpreciseStyle_Internal>,
~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:89:7 - error TS1005: ';' expected.
89 +key: $Keys<____DangerouslyImpreciseStyle_Internal>,
~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:89:54 - error TS1109: Expression expected.
89 +key: $Keys<____DangerouslyImpreciseStyle_Internal>,
~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:90:1 - error TS1109: Expression expected.
90 > = $ElementType<____DangerouslyImpreciseStyle_Internal, key>;
~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:90:3 - error TS1109: Expression expected.
90 > = $ElementType<____DangerouslyImpreciseStyle_Internal, key>;
~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:90:62 - error TS1005: '(' expected.
90 > = $ElementType<____DangerouslyImpreciseStyle_Internal, key>;
~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:253:36 - error TS1005: '=>' expected.
253 absoluteFill: (absoluteFill: any), // TODO: This should be updated after we fix downstream Flow sites.
~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:275:12 - error TS1005: ',' expected.
275 compose<T: DangerouslyImpreciseStyleProp>(
~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:280:31 - error TS1005: ')' expected.
280 return ([style1, style2]: $ReadOnlyArray<T>);
~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:280:50 - error TS1005: '(' expected.
280 return ([style1, style2]: $ReadOnlyArray<T>);
~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:361:10 - error TS1139: Type parameter declaration expected.
361 create<+S: ____Styles_Internal>(obj: S): $ObjMap<S, (Object) => any> {
~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:361:12 - error TS1005: ';' expected.
361 create<+S: ____Styles_Internal>(obj: S): $ObjMap<S, (Object) => any> {
~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:361:38 - error TS1005: ')' expected.
361 create<+S: ____Styles_Internal>(obj: S): $ObjMap<S, (Object) => any> {
~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:361:41 - error TS1005: ';' expected.
361 create<+S: ____Styles_Internal>(obj: S): $ObjMap<S, (Object) => any> {
~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:361:42 - error TS1128: Declaration or statement expected.
361 create<+S: ____Styles_Internal>(obj: S): $ObjMap<S, (Object) => any> {
~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:373:5 - error TS1005: ',' expected.
373 return obj;
~~~~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:373:12 - error TS1005: ':' expected.
373 return obj;
~~~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:373:15 - error TS1005: ',' expected.
373 return obj;
~
node_modules/react-native/Libraries/StyleSheet/StyleSheet.js:375:1 - error TS1109: Expression expected.
375 };
~
-----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files | 95.24 | 71.43 | 100 | 94.44 | |
actions | 100 | 100 | 100 | 100 | |
index.ts | 100 | 100 | 100 | 100 | |
reducers | 92.31 | 71.43 | 100 | 92.31 | |
index.ts | 92.31 | 71.43 | 100 | 92.31 | 34 |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 failed, 2 passed, 3 total
Tests: 8 passed, 8 total
Snapshots: 0 total
Time: 4.247s
Ran all test suites matching /src/i.
Active Filters: filename /src/
› Press c to clear filters.
Watch Usage
› Press a to run all tests.
› Press f to run only failed tests.
› Press o to only run tests related to changed files.
› Press q to quit watch mode.
› Press t to filter by a test name regex pattern.
› Press p to filter by a filename regex pattern.
› Press Enter to trigger a test run.
我的 package.json jest 部分如下所示:
"jest": {
"preset": "react-native",
"verbose": true,
"clearMocks": true,
"collectCoverage": true,
"globals": {
"__DEV__": true
},
"transform": {
"^.+\\.(t|j)sx?$": "ts-jest"
},
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"moduleDirectories": [
"node_modules",
"src"
],
"testMatch": [
"**/**/*.(test|spec).(tsx|ts|js)"
],
"transformIgnorePatterns": [
"node_modules/(?!(react-native|jest-styled-components|styled-components)/)"
],
"testEnvironment": "node"
}
所以我看到错误来自流类型的 react-native StyleSheet libnode_modules/react-native/Libraries/StyleSheet/StyleSheet.js
我的 tsconfig.json 看起来像这样:
{
"compilerOptions": {
"target": "es2016",
"module": "esnext",
"moduleResolution": "node",
"jsx": "react",
"outDir": "artifacts",
"rootDir": "src",
"allowSyntheticDefaultImports": true,
"noImplicitAny": false,
"preserveConstEnums": true,
"allowJs": true,
"pretty": true,
"sourceMap": true,
"noImplicitReturns": true,
"noUnusedParameters": true,
"noUnusedLocals": true,
"skipLibCheck": true,
"baseUrl": ".",
"importHelpers": true,
"paths": {
"*": ["src/*"]
}
},
"include": ["./src/**/*"],
"filesGlob": ["typings/index.d.ts", "src/**/*.ts", "src/**/*.tsx"],
"types": ["react", "react-native", "jest"],
"exclude": ["android", "ios", "build", "node_modules", "**/*.js"],
"compileOnSave": false,
"lib": ["dom", "es7"]
}
我在网上搜索任何线索,使用transformIgnorePatterns
tsconfig 和 tsconfig 的值无济于事。
当我在 ios/android 中运行项目时,它可以编译并正常工作。
这是回购: