Skip to content

Commit 6b2a511

Browse files
Luna Weifacebook-github-bot
Luna Wei
authored andcommitted
Move TypeScript declarations into react-native (#34614)
Summary: ## Changelog [General] [Added] - Add `types` folder to house TypeScript types. Release TypesScript types with react-native and eventually deprecate [types/react-native](https://www.npmjs.com/package/types/react-native). The current plan is to release types/react-native for 0.70 and 0.71 while also maintaining types here. This will result in some double maintenance until 0.72 but will give community time to move off of types/react-native. After this lands, there have been changes on `main` of types that we need to update. Then, when we release 0.71 from DefinitelyTyped, we can simply copy over the `types` folder from this repo. Pull Request resolved: #34614 Test Plan: `yarn run test-typescript` for linting types * Created a new project using the TS template and my local clone of `react-native` on this branch. `npx react-native init MyTSApp --version <path-to-my-local-rn-repo> --template react-native-template-typescript` * Updated the `package.json` to remove `types/react-native` * Deleted my node_modules and re-ran yarn * Opened MyTSApp in VSCode and verified the type suggestions appeared and cmd+click to defnitions took me to the node_module dependency `react-native/types` ## Danger is failing on this PR and it's expected as it runs off the changes on `main`. [This is expected](https://docs.github.com/en/github-ae@latest/actions/using-workflows/events-that-trigger-workflows?fbclid=IwAR2_AE0Jwndt8Gu-iTQnxGxLJq7nakbi7sz8jwZ6U62JWLSdcZuvjcQ6WvE#pull_request_target). However testing it locally passes. Once merged, and these changes are on `main`, danger will pass again. ``` $ react-native/packages/react-native-bots ❯ yarn danger pr #34614 yarn run v1.22.19 $ ..react-native/node_modules/.bin/danger pr #34614 Starting Danger PR on #34614 Danger: ✓ found only warnings, not failing the build ## Warnings :lock: package.json - <i>Changes were made to package.json. This will require a manual import by a Facebook employee.</i> ✨ Done in 13.24s. ``` Reviewed By: mdvacca Differential Revision: D39479137 Pulled By: lunaleaps fbshipit-source-id: 1d506f812d566b783b6e79104cd6339b077a42a7
1 parent ab5f26b commit 6b2a511

24 files changed

+15357
-27
lines changed

.circleci/config.yml

+5
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,11 @@ jobs:
345345
command: yarn flow-check-android
346346
when: always
347347

348+
- run:
349+
name: Run TypeScript tests
350+
command: yarn test-typescript
351+
when: always
352+
348353
- run:
349354
name: Sanity checks
350355
command: |

.eslintrc.js

+12
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,17 @@ module.exports = {
7171
jest: true,
7272
},
7373
},
74+
{
75+
files: ['types/**/*.{ts,tsx}'],
76+
parser: '@typescript-eslint/parser',
77+
plugins: ['@typescript-eslint/eslint-plugin'],
78+
rules: {
79+
'@typescript-eslint/no-unused-vars': 'off',
80+
'react-native/no-inline-styles': 'off',
81+
'@typescript-eslint/no-shadow': 'off',
82+
'no-self-compare': 'off',
83+
'react/self-closing-comp': 'off',
84+
},
85+
},
7486
],
7587
};

package.json

+5-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"engines": {
1010
"node": ">=14"
1111
},
12+
"types": "types",
1213
"jest-junit": {
1314
"outputDirectory": "reports/junit",
1415
"outputName": "js-test-results.xml"
@@ -81,8 +82,8 @@
8182
"shellcheck": "./scripts/circleci/analyze_scripts.sh",
8283
"clang-format": "clang-format -i --glob=*/**/*.{h,cpp,m,mm}",
8384
"format": "npm run prettier && npm run clang-format",
84-
"prettier": "prettier --write \"./**/*.{js,md,yml}\"",
85-
"format-check": "prettier --list-different \"./**/*.{js,md,yml}\"",
85+
"prettier": "prettier --write \"./**/*.{js,md,yml,ts,tsx}\"",
86+
"format-check": "prettier --list-different \"./**/*.{js,md,yml,ts,tsx}\"",
8687
"update-lock": "npx yarn-deduplicate",
8788
"docker-setup-android": "docker pull reactnativecommunity/react-native-android:5.2",
8889
"docker-build-android": "docker build -t reactnativeci/android -f .circleci/Dockerfiles/Dockerfile.android .",
@@ -93,7 +94,8 @@
9394
"test-android-instrumentation": "yarn run docker-build-android && yarn run test-android-run-instrumentation",
9495
"test-android-unit": "yarn run docker-build-android && yarn run test-android-run-unit",
9596
"test-android-e2e": "yarn run docker-build-android && yarn run test-android-run-e2e",
96-
"test-ios": "./scripts/objc-test.sh test"
97+
"test-ios": "./scripts/objc-test.sh test",
98+
"test-typescript": "dtslint types"
9799
},
98100
"workspaces": [
99101
"packages/*",

repo-config/package.json

+4
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313
"@babel/eslint-parser": "^7.18.2",
1414
"@babel/generator": "^7.14.0",
1515
"@babel/plugin-transform-regenerator": "^7.0.0",
16+
"@definitelytyped/dtslint": "^0.0.127",
1617
"@react-native-community/eslint-plugin": "*",
1718
"@react-native/eslint-plugin-specs": "^0.71.0",
1819
"@reactions/component": "^2.0.2",
20+
"@types/react": "^18.0.18",
21+
"@typescript-eslint/parser": "^5.30.5",
1922
"async": "^3.2.2",
2023
"clang-format": "^1.8.0",
2124
"connect": "^3.6.5",
@@ -46,6 +49,7 @@
4649
"react-test-renderer": "18.2.0",
4750
"shelljs": "^0.8.5",
4851
"signedsource": "^1.0.0",
52+
"typescript": "4.1.3",
4953
"ws": "^6.1.4",
5054
"yargs": "^17.5.1"
5155
},

scripts/.npmignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# Make sure we never publish __test__ folders (Gradle output)
2-
**/__tests__/
2+
**/__*tests__/

types/BatchedBridge.d.ts

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
*/
9+
10+
interface SpyData {
11+
type: number;
12+
module?: string | undefined;
13+
method: string | number;
14+
args: any[];
15+
}
16+
17+
declare class MessageQueue {
18+
static spy(spyOrToggle: boolean | ((data: SpyData) => void)): void;
19+
20+
getCallableModule(name: string): Object;
21+
registerCallableModule(name: string, module: Object): void;
22+
registerLazyCallableModule(name: string, factory: () => Object): void;
23+
}
24+
25+
declare module 'react-native/Libraries/BatchedBridge/BatchedBridge' {
26+
const BatchedBridge: MessageQueue;
27+
export default BatchedBridge;
28+
}
29+
30+
declare module 'react-native/Libraries/BatchedBridge/MessageQueue' {
31+
export default MessageQueue;
32+
}

types/Codegen.d.ts

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
*/
9+
10+
declare module 'react-native/Libraries/Utilities/codegenNativeCommands' {
11+
export interface Options<T extends string> {
12+
readonly supportedCommands: ReadonlyArray<T>;
13+
}
14+
15+
function codegenNativeCommands<T extends object>(
16+
options: Options<keyof T extends string ? keyof T : never>,
17+
): T;
18+
19+
export default codegenNativeCommands;
20+
}
21+
22+
declare module 'react-native/Libraries/Utilities/codegenNativeComponent' {
23+
import type {HostComponent} from 'react-native';
24+
25+
export interface Options {
26+
readonly interfaceOnly?: boolean;
27+
readonly paperComponentName?: string;
28+
readonly paperComponentNameDeprecated?: string;
29+
readonly excludedPlatforms?: ReadonlyArray<'iOS' | 'android'>;
30+
}
31+
32+
export type NativeComponentType<T> = HostComponent<T>;
33+
34+
function codegenNativeComponent<Props extends object>(
35+
componentName: string,
36+
options?: Options,
37+
): NativeComponentType<Props>;
38+
39+
export default codegenNativeComponent;
40+
}
41+
42+
declare module 'react-native/Libraries/Types/CodegenTypes' {
43+
import type {NativeSyntheticEvent} from 'react-native';
44+
45+
// Event types
46+
// We're not using the PaperName, it is only used to codegen view config settings
47+
48+
export type BubblingEventHandler<
49+
T,
50+
PaperName extends string | never = never,
51+
> = (event: NativeSyntheticEvent<T>) => void | Promise<void>;
52+
export type DirectEventHandler<
53+
T,
54+
PaperName extends string | never = never,
55+
> = (event: NativeSyntheticEvent<T>) => void | Promise<void>;
56+
57+
// Prop types
58+
export type Double = number;
59+
export type Float = number;
60+
export type Int32 = number;
61+
export type UnsafeObject = object;
62+
63+
type DefaultTypes = number | boolean | string | ReadonlyArray<string>;
64+
// Default handling, ignore the unused value
65+
// we're only using it for type checking
66+
//
67+
// TODO: (rickhanlonii) T44881457 If a default is provided, it should always be optional
68+
// but that is currently not supported in the codegen since we require a default
69+
70+
export type WithDefault<
71+
Type extends DefaultTypes,
72+
Value extends Type | string | undefined | null,
73+
> = Type | undefined | null;
74+
}

types/Devtools.d.ts

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
*/
9+
10+
declare module 'react-native/Libraries/Core/Devtools/parseErrorStack' {
11+
export type StackFrame = {
12+
file: string;
13+
methodName: string;
14+
lineNumber: number;
15+
column: number | null;
16+
};
17+
18+
export interface ExtendedError extends Error {
19+
framesToPop?: number | undefined;
20+
}
21+
22+
export default function parseErrorStack(error: ExtendedError): StackFrame[];
23+
}
24+
25+
declare module 'react-native/Libraries/Core/Devtools/symbolicateStackTrace' {
26+
import {StackFrame} from 'react-native/Libraries/Core/Devtools/parseErrorStack';
27+
28+
export default function symbolicateStackTrace(
29+
stack: ReadonlyArray<StackFrame>,
30+
): Promise<StackFrame[]>;
31+
}

types/LaunchScreen.d.ts

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
*/
9+
10+
// Adds the JSX elements used in the launch screen.
11+
12+
declare module 'react-native/Libraries/NewAppScreen' {
13+
export const Header: any;
14+
export const LearnMoreLinks: any;
15+
export const Colors: any;
16+
export const DebugInstructions: any;
17+
export const ReloadInstructions: any;
18+
}

0 commit comments

Comments
 (0)