aws-amplify / aws-amplify/amplify-data

Export generic type NeverEmpty<T> from api-graphql

Open
#473 2 comments 0 reactions 1 assignee Claimed by @nadetastic View on GitHub
feature-request 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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.