Describe the bug
I get Type error when I try to use __typename inside async function
const signInWithEmail: MutationResolvers["signInWithEmail"] = () => {
return {
__typename: "LoginResponse",
token: "token"
}
}
but here when I add async I get the error
const signInWithEmail: MutationResolvers["signInWithEmail"] = async () => {
return {
__typename: "LoginResponse",
token: "token"
}
}
The error
TS2322: Type '() => Promise<{ __typename: string; token: string; }>' is not assignable to type 'ResolverFn<LoginResponse | UserError | Promise<LoginResponse> | Promise<UserError>, {}, any, RequireFields<MutationSignInWithEmailArgs, "input">> | StitchingResolver<...> | undefined'.
  Type '() => Promise<{ __typename: string; token: string; }>' is not assignable to type 'ResolverFn<LoginResponse | UserError | Promise<LoginResponse> | Promise<UserError>, {}, any, RequireFields<MutationSignInWithEmailArgs, "input">>'.
    Type 'Promise<{ __typename: string; token: string; }>' is not assignable to type 'LoginResponse | UserError | Promise<LoginResponse> | Promise<UserError> | Promise<LoginResponse | UserError | Promise<...> | Promise<...>>'.
      Type 'Promise<{ __typename: string; token: string; }>' is not assignable to type 'Promise<LoginResponse>'.
Type '{ __typename: string; token: string; }' is not assignable to type 'LoginResponse'.
          Types of property '__typename' are incompatible.
            Type 'string' is not assignable to type '"LoginResponse" | undefined'.
input SignInInfo {
email: String!
password: String!
}
type LoginResponse {
token: String!
}
union SignInResult = LoginResponse | UserError
type Mutation {
signInWithEmail(input: SignInInfo!): SignInResult!
}
type UserError {
message: String!
}
codegen.yml config file:overwrite: true
schema: "http://localhost:4000/"
documents: null
generates:
src/generated/graphql.ts:
plugins:
- "typescript"
- "typescript-resolvers"
config:
useIndexSignature: true
Expected behavior
Environment:
"@graphql-codegen/cli": "^1.12.2""@graphql-codegen/typescript": "1.12.2""@graphql-codegen/typescript-resolvers": "^1.12.2"@kamilkisiela can you please take a look?
@dotansimha I don't think there's something we could do... It's TypeScript that has no idea how to compare a string with an actual value.
adding as const will solve the problem on consumer-side.
@moun3iim In your example, if you set "LoginResponse" as const then it will treat it as a value not as a string.
This type of annotation is called const assertions. Here's more about the problem: https://devblogs.microsoft.com/typescript/announcing-typescript-3-4-rc/. It's available since TypeScript 3.4.
@dotansimha another solution but more "painful" to developers could be to let typescript-resolvers generate enum Typename { LoginResponse = 'LoginResponse' ... } and make all signatures expect an enum value. Then in resolvers instead of using __typename: 'LoginResponse' you use __typename: Typename.LoginResponse.
@kamilkisiela we can generate const assertions in base typescript already, it's done by @DragorWW in https://github.com/dotansimha/graphql-code-generator/pull/3569 , is it enough for that? or something is still missing?
@dotansimha I don't think there's something we could do... It's TypeScript that has no idea how to compare a string with an actual value.
adding
as constwill solve the problem on consumer-side.@moun3iim In your example, if you set
"LoginResponse" as constthen it will treat it as a value not as a string.This type of annotation is called
const assertions. Here's more about the problem: https://devblogs.microsoft.com/typescript/announcing-typescript-3-4-rc/. It's available since TypeScript 3.4.@dotansimha another solution but more "painful" to developers could be to let
typescript-resolversgenerateenum Typename { LoginResponse = 'LoginResponse' ... }and make all signatures expect an enum value. Then in resolvers instead of using__typename: 'LoginResponse'you use__typename: Typename.LoginResponse.
I can't understand, should I edit "LoginResponse" in the generated file !!
@moun3iim no, you should add it to the code you are writing :)
const signInWithEmail: MutationResolvers["signInWithEmail"] = async () => {
return {
__typename: "LoginResponse" as const, // < here
token: "token"
}
}
Looks like this is no longer working with TS 4.0.2–using "ResultName" as const does not remove the error; like OP, though, removing async does remove the error.
It makes sense, since it marks the function as real async function, and not just as a regular function that returns a Promise.
@joeyfigaro any example for the TS4.2 issue? how can I reproduce this?
Fair questions @dotansimha — I think my issue is unrelated to the issue described here. I'm going to open up a new ticket with a repro. :)