Skip to content

Commit

Permalink
Move TypeScript declarations into react-native (#34614)
Browse files Browse the repository at this point in the history
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: a7398492386abee9543b3bb5d98682cdf15f54da
  • Loading branch information
Luna Wei authored and facebook-github-bot committed Sep 17, 2022
1 parent d15a82d commit fbcba62
Show file tree
Hide file tree
Showing 24 changed files with 15,357 additions and 27 deletions.
5 changes: 5 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,11 @@ jobs:
command: yarn flow-check-android
when: always

- run:
name: Run TypeScript tests
command: yarn test-typescript
when: always

- run:
name: Sanity checks
command: |
Expand Down
12 changes: 12 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,17 @@ module.exports = {
jest: true,
},
},
{
files: ['types/**/*.{ts,tsx}'],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint/eslint-plugin'],
rules: {
'@typescript-eslint/no-unused-vars': 'off',
'react-native/no-inline-styles': 'off',
'@typescript-eslint/no-shadow': 'off',
'no-self-compare': 'off',
'react/self-closing-comp': 'off',
},
},
],
};
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"engines": {
"node": ">=14"
},
"types": "types",
"jest-junit": {
"outputDirectory": "reports/junit",
"outputName": "js-test-results.xml"
Expand Down Expand Up @@ -81,8 +82,8 @@
"shellcheck": "./scripts/circleci/analyze_scripts.sh",
"clang-format": "clang-format -i --glob=*/**/*.{h,cpp,m,mm}",
"format": "npm run prettier && npm run clang-format",
"prettier": "prettier --write \"./**/*.{js,md,yml}\"",
"format-check": "prettier --list-different \"./**/*.{js,md,yml}\"",
"prettier": "prettier --write \"./**/*.{js,md,yml,ts,tsx}\"",
"format-check": "prettier --list-different \"./**/*.{js,md,yml,ts,tsx}\"",
"update-lock": "npx yarn-deduplicate",
"docker-setup-android": "docker pull reactnativecommunity/react-native-android:5.2",
"docker-build-android": "docker build -t reactnativeci/android -f .circleci/Dockerfiles/Dockerfile.android .",
Expand All @@ -93,7 +94,8 @@
"test-android-instrumentation": "yarn run docker-build-android && yarn run test-android-run-instrumentation",
"test-android-unit": "yarn run docker-build-android && yarn run test-android-run-unit",
"test-android-e2e": "yarn run docker-build-android && yarn run test-android-run-e2e",
"test-ios": "./scripts/objc-test.sh test"
"test-ios": "./scripts/objc-test.sh test",
"test-typescript": "dtslint types"
},
"workspaces": [
"packages/*",
Expand Down
4 changes: 4 additions & 0 deletions repo-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@
"@babel/eslint-parser": "^7.18.2",
"@babel/generator": "^7.14.0",
"@babel/plugin-transform-regenerator": "^7.0.0",
"@definitelytyped/dtslint": "^0.0.127",
"@react-native-community/eslint-plugin": "*",
"@react-native/eslint-plugin-specs": "^0.71.0",
"@reactions/component": "^2.0.2",
"@types/react": "^18.0.18",
"@typescript-eslint/parser": "^5.30.5",
"async": "^3.2.2",
"clang-format": "^1.8.0",
"connect": "^3.6.5",
Expand Down Expand Up @@ -46,6 +49,7 @@
"react-test-renderer": "18.2.0",
"shelljs": "^0.8.5",
"signedsource": "^1.0.0",
"typescript": "4.1.3",
"ws": "^6.1.4",
"yargs": "^17.5.1"
},
Expand Down
2 changes: 1 addition & 1 deletion scripts/.npmignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Make sure we never publish __test__ folders (Gradle output)
**/__tests__/
**/__*tests__/
32 changes: 32 additions & 0 deletions types/BatchedBridge.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/

interface SpyData {
type: number;
module?: string | undefined;
method: string | number;
args: any[];
}

declare class MessageQueue {
static spy(spyOrToggle: boolean | ((data: SpyData) => void)): void;

getCallableModule(name: string): Object;
registerCallableModule(name: string, module: Object): void;
registerLazyCallableModule(name: string, factory: () => Object): void;
}

declare module 'react-native/Libraries/BatchedBridge/BatchedBridge' {
const BatchedBridge: MessageQueue;
export default BatchedBridge;
}

declare module 'react-native/Libraries/BatchedBridge/MessageQueue' {
export default MessageQueue;
}
74 changes: 74 additions & 0 deletions types/Codegen.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/

declare module 'react-native/Libraries/Utilities/codegenNativeCommands' {
export interface Options<T extends string> {
readonly supportedCommands: ReadonlyArray<T>;
}

function codegenNativeCommands<T extends object>(
options: Options<keyof T extends string ? keyof T : never>,
): T;

export default codegenNativeCommands;
}

declare module 'react-native/Libraries/Utilities/codegenNativeComponent' {
import type {HostComponent} from 'react-native';

export interface Options {
readonly interfaceOnly?: boolean;
readonly paperComponentName?: string;
readonly paperComponentNameDeprecated?: string;
readonly excludedPlatforms?: ReadonlyArray<'iOS' | 'android'>;
}

export type NativeComponentType<T> = HostComponent<T>;

function codegenNativeComponent<Props extends object>(
componentName: string,
options?: Options,
): NativeComponentType<Props>;

export default codegenNativeComponent;
}

declare module 'react-native/Libraries/Types/CodegenTypes' {
import type {NativeSyntheticEvent} from 'react-native';

// Event types
// We're not using the PaperName, it is only used to codegen view config settings

export type BubblingEventHandler<
T,
PaperName extends string | never = never,
> = (event: NativeSyntheticEvent<T>) => void | Promise<void>;
export type DirectEventHandler<
T,
PaperName extends string | never = never,
> = (event: NativeSyntheticEvent<T>) => void | Promise<void>;

// Prop types
export type Double = number;
export type Float = number;
export type Int32 = number;
export type UnsafeObject = object;

type DefaultTypes = number | boolean | string | ReadonlyArray<string>;
// Default handling, ignore the unused value
// we're only using it for type checking
//
// TODO: (rickhanlonii) T44881457 If a default is provided, it should always be optional
// but that is currently not supported in the codegen since we require a default

export type WithDefault<
Type extends DefaultTypes,
Value extends Type | string | undefined | null,
> = Type | undefined | null;
}
31 changes: 31 additions & 0 deletions types/Devtools.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/

declare module 'react-native/Libraries/Core/Devtools/parseErrorStack' {
export type StackFrame = {
file: string;
methodName: string;
lineNumber: number;
column: number | null;
};

export interface ExtendedError extends Error {
framesToPop?: number | undefined;
}

export default function parseErrorStack(error: ExtendedError): StackFrame[];
}

declare module 'react-native/Libraries/Core/Devtools/symbolicateStackTrace' {
import {StackFrame} from 'react-native/Libraries/Core/Devtools/parseErrorStack';

export default function symbolicateStackTrace(
stack: ReadonlyArray<StackFrame>,
): Promise<StackFrame[]>;
}
18 changes: 18 additions & 0 deletions types/LaunchScreen.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/

// Adds the JSX elements used in the launch screen.

declare module 'react-native/Libraries/NewAppScreen' {
export const Header: any;
export const LearnMoreLinks: any;
export const Colors: any;
export const DebugInstructions: any;
export const ReloadInstructions: any;
}
Loading

0 comments on commit fbcba62

Please sign in to comment.