Skip to content

Commit

Permalink
fix(types): enable TypeScript libCheck & resolve type conflicts (#4306)
Browse files Browse the repository at this point in the history
* chore: enable TypeScript libcheck & remove "dom" lib
    "dom" conflicts with @types/react-native
* chore: add react types (referenced by admob types)
* refactor(types, app): move "app" exports to top-level exports, rather than module declarations with namespace extensions
* refactor(types): use top-level exports for module types, rather than declarations
* refactor(types): for JSON config, augment existing `ReactNativeFirebase` namespace from /app
    Re-exporting the namespace causes collision issues -- tramples previous values rather than merging
* fix(types, admob): Use string-indexing rather than dot-notation for referring to interface keys
* fix(types, analytics): convert missing interface to `any`
* fix(types, database): missing `value` type (treated as 'any')
* fix(types, dynamic-links): fix dynamic-links `onLink` function type
    "Function" is not generic
* fix(types, firestore): add missing generic to Promise type
    Keep current behavior with `any`
* fix(types, messaging): remove parameter initializer in typedef 
    Only allowed in implementations
* fix(types, messaging): avoid implicit `any` via `void` return type for `setBackgroundMessageHandler`
* fix(types, ml-vision): import non-ambient types in BarcodeDetectorTypes
* fix(types, ml-vision): import non-ambient types in root module from BarcodeDetectorTypes
* fix(types, ml-vision): repair invalid `extends` use by duplicating inherited key
    Could have Omit<>'ed the incompatible `bounds` key, but duplicating the one inherited key seemed less complex
* fix(types, perf): add void return types to untyped perf methods
* tests(admob): add type override to intentionally-wrong syntax
    Incorrect type is now caught by TS
* tests(types, ml-vision): fix ml-vision test typo, exposed by proper types
    VisionBarcodeFormat.ALL_POINTS does not exist
* chore(website): update typedoc to allow recursive types
    uses new syntax: TSConfigReader
  • Loading branch information
davidgovea authored Sep 30, 2020
1 parent 61df91f commit aa8ee8b
Show file tree
Hide file tree
Showing 25 changed files with 468 additions and 538 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"@babel/preset-env": "7.9.5",
"@babel/preset-flow": "7.9.0",
"@types/jest": "^25.2.1",
"@types/react": "^16.9.49",
"@types/react-native": "^0.62.0",
"@typescript-eslint/eslint-plugin": "^2.18.0",
"@typescript-eslint/parser": "^2.18.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/admob/__tests__/admob.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { firebase } from '../lib';
import { firebase, FirebaseAdMobTypes } from '../lib';

describe('Admob', () => {
describe('namespace', () => {
Expand All @@ -21,7 +21,7 @@ describe('Admob', () => {
it('throws if maxAdContentRating is invalid', () => {
expect(() =>
firebase.admob().setRequestConfiguration({
maxAdContentRating: 'Y',
maxAdContentRating: 'Y' as FirebaseAdMobTypes.MaxAdContentRating[keyof FirebaseAdMobTypes.MaxAdContentRating],
}),
).toThrowError(
"firebase.admob().setRequestConfiguration(*) 'requestConfiguration.maxAdContentRating' expected on of MaxAdContentRating.G, MaxAdContentRating.PG, MaxAdContentRating.T or MaxAdContentRating.MA",
Expand Down
174 changes: 84 additions & 90 deletions packages/admob/lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
* limitations under the License.
*
*/

import { ReactNativeFirebase } from '@react-native-firebase/app';
import * as React from 'react';

/**
* Firebase Admob package for React Native.
Expand Down Expand Up @@ -398,9 +398,9 @@ export namespace FirebaseAdMobTypes {
*/
setDebugGeography(
geography:
| AdsConsentDebugGeography.DISABLED
| AdsConsentDebugGeography.EEA
| AdsConsentDebugGeography.NOT_EEA,
| AdsConsentDebugGeography['DISABLED']
| AdsConsentDebugGeography['EEA']
| AdsConsentDebugGeography['NOT_EEA'],
): Promise<void>;

/**
Expand All @@ -424,9 +424,9 @@ export namespace FirebaseAdMobTypes {
*/
setStatus(
status:
| AdsConsentStatus.UNKNOWN
| AdsConsentStatus.NON_PERSONALIZED
| AdsConsentStatus.PERSONALIZED,
| AdsConsentStatus['UNKNOWN']
| AdsConsentStatus['NON_PERSONALIZED']
| AdsConsentStatus['PERSONALIZED'],
): Promise<void>;

/**
Expand All @@ -443,7 +443,9 @@ export namespace FirebaseAdMobTypes {
* ```
*/
getStatus(): Promise<
AdsConsentStatus.UNKNOWN | AdsConsentStatus.NON_PERSONALIZED | AdsConsentStatus.PERSONALIZED
| AdsConsentStatus['UNKNOWN']
| AdsConsentStatus['NON_PERSONALIZED']
| AdsConsentStatus['PERSONALIZED']
>;

/**
Expand Down Expand Up @@ -537,9 +539,9 @@ export namespace FirebaseAdMobTypes {
* - PERSONALIZED: The user has accepted personalized ads.
*/
status:
| AdsConsentStatus.UNKNOWN
| AdsConsentStatus.NON_PERSONALIZED
| AdsConsentStatus.PERSONALIZED;
| AdsConsentStatus['UNKNOWN']
| AdsConsentStatus['NON_PERSONALIZED']
| AdsConsentStatus['PERSONALIZED'];

/**
* If `true`, the user requested an ad-free version of your application.
Expand All @@ -559,9 +561,9 @@ export namespace FirebaseAdMobTypes {
* - PERSONALIZED: The user has accepted personalized ads.
*/
status:
| AdsConsentStatus.UNKNOWN
| AdsConsentStatus.NON_PERSONALIZED
| AdsConsentStatus.PERSONALIZED;
| AdsConsentStatus['UNKNOWN']
| AdsConsentStatus['NON_PERSONALIZED']
| AdsConsentStatus['PERSONALIZED'];

/**
* If `true` the user is within the EEA or their location could not be determined.
Expand Down Expand Up @@ -768,10 +770,10 @@ export namespace FirebaseAdMobTypes {
* Ratings are based on the [digital content label classifications](https://support.google.com/admob/answer/7562142).
*/
maxAdContentRating?:
| MaxAdContentRating.G
| MaxAdContentRating.PG
| MaxAdContentRating.T
| MaxAdContentRating.MA;
| MaxAdContentRating['G']
| MaxAdContentRating['PG']
| MaxAdContentRating['T']
| MaxAdContentRating['MA'];

/**
* If `true`, indicates that you want your content treated as child-directed for purposes of COPPA.
Expand Down Expand Up @@ -843,14 +845,14 @@ export namespace FirebaseAdMobTypes {
*/
export type AdEventListener = (
type:
| AdEventType.LOADED
| AdEventType.ERROR
| AdEventType.OPENED
| AdEventType.CLICKED
| AdEventType.LEFT_APPLICATION
| AdEventType.CLOSED
| RewardedAdEventType.LOADED
| RewardedAdEventType.EARNED_REWARD,
| AdEventType['LOADED']
| AdEventType['ERROR']
| AdEventType['OPENED']
| AdEventType['CLICKED']
| AdEventType['LEFT_APPLICATION']
| AdEventType['CLOSED']
| RewardedAdEventType['LOADED']
| RewardedAdEventType['EARNED_REWARD'],
error?: Error,
data?: any | RewardedAdReward,
) => void;
Expand Down Expand Up @@ -1180,35 +1182,29 @@ export namespace FirebaseAdMobTypes {
}
}

declare module '@react-native-firebase/admob' {
// tslint:disable-next-line:no-duplicate-imports required otherwise doesn't work
import { ReactNativeFirebase } from '@react-native-firebase/app';
import React from 'react';
import ReactNativeFirebaseModule = ReactNativeFirebase.Module;
import FirebaseModuleWithStaticsAndApp = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp;
import BannerAd = FirebaseAdMobTypes.BannerAd;

const firebaseNamedExport: {} & ReactNativeFirebaseModule;
export const firebase = firebaseNamedExport;

export const AdsConsentDebugGeography: {} & FirebaseAdMobTypes.AdsConsentDebugGeography;
export const AdsConsentStatus: {} & FirebaseAdMobTypes.AdsConsentStatus;
export const MaxAdContentRating: {} & FirebaseAdMobTypes.MaxAdContentRating;
export const TestIds: {} & FirebaseAdMobTypes.TestIds;
export const AdEventType: {} & FirebaseAdMobTypes.AdEventType;
export const BannerAdSize: {} & FirebaseAdMobTypes.BannerAdSize;
export const RewardedAdEventType: {} & FirebaseAdMobTypes.RewardedAdEventType;
export const AdsConsent: {} & FirebaseAdMobTypes.AdsConsent;
export const InterstitialAd: typeof FirebaseAdMobTypes.InterstitialAd;
export const RewardedAd: typeof FirebaseAdMobTypes.RewardedAd;
export const BannerAd: React.SFC<BannerAd>;

const defaultExport: FirebaseModuleWithStaticsAndApp<
FirebaseAdMobTypes.Module,
FirebaseAdMobTypes.Statics
>;
export default defaultExport;
}
export const AdsConsentDebugGeography: FirebaseAdMobTypes.AdsConsentDebugGeography;
export const AdsConsentStatus: FirebaseAdMobTypes.AdsConsentStatus;
export const MaxAdContentRating: FirebaseAdMobTypes.MaxAdContentRating;
export const TestIds: FirebaseAdMobTypes.TestIds;
export const AdEventType: FirebaseAdMobTypes.AdEventType;
export const BannerAdSize: FirebaseAdMobTypes.BannerAdSize;
export const RewardedAdEventType: FirebaseAdMobTypes.RewardedAdEventType;
export const AdsConsent: FirebaseAdMobTypes.AdsConsent;
export const InterstitialAd: typeof FirebaseAdMobTypes.InterstitialAd;
export const RewardedAd: typeof FirebaseAdMobTypes.RewardedAd;
export const BannerAd: React.SFC<FirebaseAdMobTypes.BannerAd>;

declare const defaultExport: ReactNativeFirebase.FirebaseModuleWithStaticsAndApp<
FirebaseAdMobTypes.Module,
FirebaseAdMobTypes.Statics
>;

export const firebase: ReactNativeFirebase.Module & {
storage: typeof defaultExport;
app(name?: string): ReactNativeFirebase.FirebaseApp & { admob(): FirebaseAdMobTypes.Module };
};

export default defaultExport;

/**
* Attach namespace to `firebase.` and `FirebaseApp.`.
Expand All @@ -1224,41 +1220,39 @@ declare module '@react-native-firebase/app' {
interface FirebaseApp {
admob(): FirebaseAdMobTypes.Module;
}
}
}

namespace ReactNativeFirebase {
interface FirebaseJsonConfig {
/**
* The Google AdMob application App ID for Android.
*
* This can be found under: Apps > App settings > App ID on the Google AdMob dashboard.
*
* For testing purposes, use the App ID: `ca-app-pub-3940256099942544~3347511713`.
*
* @android
*/
admob_android_app_id: string;

/**
* The Google AdMob application App ID for iOS.
*
* This can be found under: Apps > App settings > App ID on the Google AdMob dashboard.
*
* For testing purposes, use the App ID: `ca-app-pub-3940256099942544~1458002511`.
*
* @ios
*/
admob_ios_app_id: string;

/**
* By default, the Google Mobile Ads SDK initializes app measurement and begins sending user-level event data to
* Google immediately when the app starts. This initialization behavior ensures you can enable AdMob user metrics
* without making additional code changes.
*
* If you require your app users to provide consent before collecting data, setting the value to `true` will prevent
* data being sent until the `firebase.admob().initialize()` method has been called.
*/
admob_delay_app_measurement_init: boolean;
interface FirebaseJsonConfig {
/**
* The Google AdMob application App ID for Android.
*
* This can be found under: Apps > App settings > App ID on the Google AdMob dashboard.
*
* For testing purposes, use the App ID: `ca-app-pub-3940256099942544~3347511713`.
*
* @android
*/
admob_android_app_id: string;

/**
* The Google AdMob application App ID for iOS.
*
* This can be found under: Apps > App settings > App ID on the Google AdMob dashboard.
*
* For testing purposes, use the App ID: `ca-app-pub-3940256099942544~1458002511`.
*
* @ios
*/
admob_ios_app_id: string;

/**
* By default, the Google Mobile Ads SDK initializes app measurement and begins sending user-level event data to
* Google immediately when the app starts. This initialization behavior ensures you can enable AdMob user metrics
* without making additional code changes.
*
* If you require your app users to provide consent before collecting data, setting the value to `true` will prevent
* data being sent until the `firebase.admob().initialize()` method has been called.
*/
admob_delay_app_measurement_init: boolean;
}
}
}
78 changes: 37 additions & 41 deletions packages/analytics/lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1262,7 +1262,7 @@ export namespace FirebaseAnalyticsTypes {
*
* @param params See {@link analytics.SetCheckoutOptionEventParameters}.
*/
logSetCheckoutOption(params: SetCheckoutOptionEventParameters): Promise<void>;
logSetCheckoutOption(params: any): Promise<void>;

/**
* Share event. Apps with social features can log the Share event to identify the most viral content.
Expand Down Expand Up @@ -1480,21 +1480,19 @@ export namespace FirebaseAnalyticsTypes {
}
}

declare module '@react-native-firebase/analytics' {
// tslint:disable-next-line:no-duplicate-imports required otherwise doesn't work
import { ReactNativeFirebase } from '@react-native-firebase/app';
import ReactNativeFirebaseModule = ReactNativeFirebase.Module;
import FirebaseModuleWithStatics = ReactNativeFirebase.FirebaseModuleWithStatics;
declare const defaultExport: ReactNativeFirebase.FirebaseModuleWithStatics<
FirebaseAnalyticsTypes.Module,
FirebaseAnalyticsTypes.Statics
>;

const firebaseNamedExport: {} & ReactNativeFirebaseModule;
export const firebase = firebaseNamedExport;
export const firebase: ReactNativeFirebase.Module & {
analytics: typeof defaultExport;
app(
name?: string,
): ReactNativeFirebase.FirebaseApp & { analytics(): FirebaseAnalyticsTypes.Module };
};

const defaultExport: FirebaseModuleWithStatics<
FirebaseAnalyticsTypes.Module,
FirebaseAnalyticsTypes.Statics
>;
export default defaultExport;
}
export default defaultExport;

/**
* Attach namespace to `firebase.` and `FirebaseApp.`.
Expand All @@ -1512,33 +1510,31 @@ declare module '@react-native-firebase/app' {
interface FirebaseApp {
analytics(): FirebaseAnalyticsTypes.Module;
}
}
}

namespace ReactNativeFirebase {
interface FirebaseJsonConfig {
/**
* Disable or enable auto collection of analytics data.
*
* This is useful for opt-in-first data flows, for example when dealing with GDPR compliance.
* This can be overridden in JavaScript.
*
* #### Example
*
* ```json
* // <project-root>/firebase.json
* {
* "react-native": {
* "analytics_auto_collection_enabled": false
* }
* }
* ```
*
* ```js
* // Re-enable analytics data collection, e.g. once user has granted permission:
* await firebase.analytics().setAnalyticsCollectionEnabled(true);
* ```
*/
analytics_auto_collection_enabled: boolean;
interface FirebaseJsonConfig {
/**
* Disable or enable auto collection of analytics data.
*
* This is useful for opt-in-first data flows, for example when dealing with GDPR compliance.
* This can be overridden in JavaScript.
*
* #### Example
*
* ```json
* // <project-root>/firebase.json
* {
* "react-native": {
* "analytics_auto_collection_enabled": false
* }
* }
* ```
*
* ```js
* // Re-enable analytics data collection, e.g. once user has granted permission:
* await firebase.analytics().setAnalyticsCollectionEnabled(true);
* ```
*/
analytics_auto_collection_enabled: boolean;
}
}
}
Loading

1 comment on commit aa8ee8b

@vercel
Copy link

@vercel vercel bot commented on aa8ee8b Sep 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.