aws-amplify / aws-amplify/amplify-data
Export generic type NeverEmpty<T> from api-graphql
- Dominant language
- TypeScript
- Stars
- 18
- Forks
- 23
- Avg merge
- 26m
- Merged PRs (30d)
- 1
Description
### Is this related to a new or existing framework?
_No response_
### Is this related to a new or existing API?
GraphQL API
### Is this related to another service?
_No response_
### Describe the feature you'd like to request
Feature I’d like to request:
I would like to be able to build upon the [GraphQL Subscription pattern provided by amplify](https://docs.amplify.aws/javascript/build-a-backend/graphqlapi/subscribe-data/) in a type-safe way. In particular, in this code snippet:
```ts
const sub = client
.graphql({
query: subscriptions.onCreateTodo,
variables
})
.subscribe({
next: ({ data }) => typeSafeHandler(data.onCreateTodo),
error: (error) => console.warn(error)
});
```
I would like to be able to handle errors in a uniform manner, while passing the `query`, `variables`, and `typeSafeHandler` items into a method such as this:
```ts
// amplify CLI generates a Subscriptions type, and this:
export type GeneratedSubscription = string & {
__generatedSubscriptionInput: InputType;
__generatedSubscriptionOutput: OutputType;
};
export type SubscriptionNames = keyof Omit;
// I like to have access to the name of the subscription:
export interface KeyedGeneratedSubscription<
NAME extends SubscriptionNames,
ARGS,
> {
gql: GeneratedSubscription>;
__subscriptionName: NAME;
}
// Here’s where the NeverEmpty issue occurs:
export type CallbackParamType = T extends KeyedGeneratedSubscription<
infer NAME,
unknown
>
? NeverEmpty>[NAME]
: never;
// so that I can have this signature for the function that handles errors uniformly:
useSubscription({
query: KeyedGeneratedSubscription,
variables: InputType,
typeSafeHandler: (result: CallbackParamType>) => void
});
```
I have this working, but it requires me to copy the source code for the type definitions for `NeverEmpty`, `WithListsFixed`, and `PagedList` out of `api-graphql/types`. That gives me a bad feeling, and I’d prefer instead to do some “right” thing.
### Describe the solution you'd like
I would like to go ahead and publicly export the `NeverEmpty` type, so that I can use it in the above code without having to copy-and-paste source code out of the `@aws-amplify/api-graphql` repo into my own repo, in order to be able to specify a wrapping signature for the `subscribe` method that handles errors uniformly and unwraps the successful notifications' results before passing them to a type-safe handler.
### Describe alternatives you've considered
It would be ideal if these types did not need to be exported, and I could nonetheless arrange something using the tools `ReturnType`, `Parameters`, `typeof`, and the `[]` types operator, as described in [this stackoverflow question](https://stackoverflow.com/questions/77783165/how-do-i-write-a-type-safe-function-signature-accepting-the-callback-function-fo).
However, there are two issues prevent this. First, the rxjs library happens to define [a deprecated overload of the `subscribe` function _after_ the one I want](https://github.com/ReactiveX/rxjs/blob/72bc92191ab959e27a969dc4476e14d95416573f/src/internal/Observable.ts#L74-L76). Inferring the parameters’ types [is going to provide this second overload’s parameters](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#inferring-within-conditional-types), eclipsing the first overload’s parameters I’m actually interested in. Second, that first `subscribe`’s definition’s parameter is a union type, but I would like to restrict only to the first part of the union. Without `NeverEmpty` to begin with, I cannot use `Exclude` to select only the first half of that union type.
### Additional context
_No response_
### Is this something that you'd be interested in working on?
- [X] 👋 I may be able to implement this feature request
- [ ] ⚠️ This feature might incur a breaking change
Contributor guide
Assessment
This issue has not been assessed yet.