mirror of
https://github.com/gosticks/DefinitelyTyped.git
synced 2026-07-01 15:50:13 +00:00
Add typings for create-subscription
This commit is contained in:
119
types/create-subscription/create-subscription-tests.tsx
Normal file
119
types/create-subscription/create-subscription-tests.tsx
Normal file
@@ -0,0 +1,119 @@
|
||||
import * as React from "react";
|
||||
import { createSubscription, Subscription } from "create-subscription";
|
||||
|
||||
//
|
||||
// Example: Subscribing to event dispatchers
|
||||
// https://github.com/facebook/react/blob/fa7fa812c70084e139d13437fb204fcdf9152299/packages/create-subscription/README.md#subscribing-to-event-dispatchers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Start with a simple component.
|
||||
// In this case, it's a functional component, but it could have been a class.
|
||||
function FollowerComponent({ followersCount }: { followersCount: number }) {
|
||||
return <div>You have {followersCount} followers!</div>;
|
||||
}
|
||||
|
||||
interface EventDispatcher<T> {
|
||||
value: T;
|
||||
addEventListener(eventName: "change", onChange: (newValue: T) => any): void;
|
||||
removeEventListener(eventName: "change", onChange: (newValue: T) => any): void;
|
||||
}
|
||||
|
||||
// Create a wrapper component to manage the subscription.
|
||||
// $ExpectType Subscription<EventDispatcher<number>, number>
|
||||
const EventHandlerSubscription = createSubscription({
|
||||
getCurrentValue: (eventDispatcher: EventDispatcher<number>) => eventDispatcher.value,
|
||||
subscribe: (eventDispatcher: EventDispatcher<number>, callback) => {
|
||||
const onChange = (event: any) => callback(eventDispatcher.value);
|
||||
eventDispatcher.addEventListener("change", onChange);
|
||||
return () => eventDispatcher.removeEventListener("change", onChange);
|
||||
}
|
||||
});
|
||||
|
||||
declare const eventDispatcher: EventDispatcher<number>;
|
||||
|
||||
// Your component can now be used as shown below.
|
||||
// In this example, 'eventDispatcher' represents a generic event dispatcher.
|
||||
<EventHandlerSubscription source={eventDispatcher}>
|
||||
{value => {
|
||||
// $ExpectType number
|
||||
const followersCount = value;
|
||||
return <FollowerComponent followersCount={followersCount} />;
|
||||
}}
|
||||
</EventHandlerSubscription>;
|
||||
|
||||
//
|
||||
// Example: Subscribing to event dispatchers
|
||||
// https://github.com/facebook/react/blob/fa7fa812c70084e139d13437fb204fcdf9152299/packages/create-subscription/README.md#subscribing-to-a-promise
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Start with a simple component.
|
||||
const LoadingComponent: React.SFC<{ loadingStatus: string | undefined }> = ({ loadingStatus }) => {
|
||||
if (loadingStatus === undefined) {
|
||||
// Loading
|
||||
} else if (loadingStatus === null) {
|
||||
// Error
|
||||
} else {
|
||||
// Success
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
// Wrap the functional component with a subscriber HOC.
|
||||
// This HOC will manage subscriptions and pass values to the decorated component.
|
||||
// It will add and remove subscriptions in an async-safe way when props change.
|
||||
// $ExpectType Subscription<Promise<string>, string | undefined>
|
||||
const PromiseSubscription = createSubscription({
|
||||
getCurrentValue: promise => {
|
||||
// There is no way to synchronously read a Promise's value,
|
||||
// So this method should return undefined.
|
||||
return undefined;
|
||||
},
|
||||
subscribe: (promise: Promise<string>, callback: (newValue: string | undefined) => void) => {
|
||||
promise.then(
|
||||
// Success
|
||||
callback,
|
||||
// Failure
|
||||
() => callback(undefined)
|
||||
);
|
||||
|
||||
// There is no way to "unsubscribe" from a Promise.
|
||||
// create-subscription will still prevent stale values from rendering.
|
||||
return () => {};
|
||||
}
|
||||
});
|
||||
|
||||
declare const loadingPromise: Promise<string>;
|
||||
|
||||
// Your component can now be used as shown below.
|
||||
<PromiseSubscription source={loadingPromise}>
|
||||
{value => {
|
||||
// $ExpectType string | undefined
|
||||
const loadingStatus = value;
|
||||
return <LoadingComponent loadingStatus={loadingStatus} />;
|
||||
}}
|
||||
</PromiseSubscription>;
|
||||
|
||||
//
|
||||
// Error cases
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
declare const wrongPromise: Promise<number>;
|
||||
|
||||
// $ExpectError
|
||||
<PromiseSubscription source={wrongPromise}>
|
||||
{value => null}
|
||||
</PromiseSubscription>;
|
||||
|
||||
// $ExpectError
|
||||
const MismatchSubscription = createSubscription({
|
||||
getCurrentValue: (a: number) => null,
|
||||
subscribe: (a: string, callback) => (() => undefined)
|
||||
});
|
||||
|
||||
// $ExpectError
|
||||
const NoUnsubscribe = createSubscription({
|
||||
getCurrentValue: (a: number) => a,
|
||||
subscribe: (a: number, callback) => {
|
||||
// oops, should've returned a callback here
|
||||
}
|
||||
});
|
||||
44
types/create-subscription/index.d.ts
vendored
Normal file
44
types/create-subscription/index.d.ts
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
// Type definitions for create-subscription 16.4
|
||||
// Project: https://github.com/facebook/react/tree/master/packages/create-subscription
|
||||
// Definitions by: Asana <https://github.com/Asana>
|
||||
// Vincent Siao <https://github.com/vsiao>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.3
|
||||
|
||||
import * as React from "react";
|
||||
|
||||
export interface SubscriptionProps<S, T> {
|
||||
children: (value: T) => React.ReactNode;
|
||||
source: S;
|
||||
}
|
||||
|
||||
export interface SubscriptionState<S, T> {
|
||||
source: S;
|
||||
value: T;
|
||||
}
|
||||
|
||||
export interface Subscription<S, T> extends React.ComponentClass<SubscriptionProps<S, T>> {}
|
||||
export type Unsubscribe = () => any;
|
||||
|
||||
export interface SubscriptionConfig<S, T> {
|
||||
/**
|
||||
* Synchronously gets the value for the subscribed property.
|
||||
* Return undefined if the subscribable value is undefined,
|
||||
* Or does not support synchronous reading (e.g. native Promise).
|
||||
*/
|
||||
getCurrentValue: (source: S) => T;
|
||||
|
||||
/**
|
||||
* Set up a subscription for the subscribable value in props, and return an unsubscribe function.
|
||||
* Return false to indicate the property cannot be unsubscribed from (e.g. native Promises).
|
||||
* Due to the variety of change event types, subscribers should provide their own handlers.
|
||||
* Those handlers should not attempt to update state though;
|
||||
* They should call the callback() instead when a subscription changes.
|
||||
*/
|
||||
subscribe: (
|
||||
source: S,
|
||||
callback: (newValue: T) => void
|
||||
) => Unsubscribe;
|
||||
}
|
||||
|
||||
export function createSubscription<S, T>(config: SubscriptionConfig<S, T>): Subscription<S, T>;
|
||||
24
types/create-subscription/tsconfig.json
Normal file
24
types/create-subscription/tsconfig.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"jsx": "react",
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6"
|
||||
],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictFunctionTypes": true,
|
||||
"strictNullChecks": true,
|
||||
"baseUrl": "../",
|
||||
"typeRoots": [
|
||||
"../"
|
||||
],
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"create-subscription-tests.tsx"
|
||||
]
|
||||
}
|
||||
1
types/create-subscription/tslint.json
Normal file
1
types/create-subscription/tslint.json
Normal file
@@ -0,0 +1 @@
|
||||
{ "extends": "dtslint/dt.json" }
|
||||
Reference in New Issue
Block a user