Nexus: typescript compiler 'authorize' does not exist in type 'NexusOutputFieldConfig<"Query","">

Created on 20 Nov 2019  路  12Comments  路  Source: graphql-nexus/nexus

typescript compiler fails to compile.

Packages:

"nexus": "^0.12.0-rc.5",
"typescript": "^3.7.2",

Error Message:

src/graphql/schema/ad/query.ts:9:7 - error TS2345: Argument of type '{ type: string; nullable: true; authorize: () => boolean; resolve: (_: any, {}: any, { services }: any) => Promise<any>; }' is not assignable to parameter of type 'NexusOutputFieldConfig<"Query", "getCompanyUsers">'.      
  Object literal may only specify known properties, and 'authorize' does not exist in type 'NexusOutputFieldConfig<"Query", "getCompanyUsers">'.

authorize: () => false,

Server Code:

import { makeSchema, fieldAuthorizePlugin } from "nexus";
const schema = makeSchema({
  types,
  outputs: {
    schema: path.join(__dirname + "/generated/schema.graphql"),
    typegen: path.join(__dirname + "/generated/typings.ts"),
  },
  typegenAutoConfig: {
    sources: [
      {
        source: path.join(__dirname, "..", "typings", "types.ts"),
        alias: "t",
      },
    ],
    contextType: "t.Context",
  },
  plugins: [fieldAuthorizePlugin()],
  prettierConfig: path.join(__dirname, "../../.prettierrc"),
});

Query Code:

import { extendType } from "nexus";

export const adQueries = extendType({
  type: "Query",
  definition(t) {
    t.list.field("getCompanyUsers", {
      type: "AdUser",
      nullable: true,
      authorize: () => false,
      resolve: async (_, {}, { services }) => {
        const items = await services.ad.getCompanyUsers("xxxx");
        return items;
      },
    });
  },
});

Most helpful comment

I'm working through the issues with some real world examples come up with some potential solutions / advice here, because this is a common pain point when getting started.

I just realized that because of how ts-node transpiles the code, it doesn't pick up the generated type defs file unless you explicitly reference it explicitly (via references or import). It may help if you add this explicitly, e.g. /// <reference path="./path-to-schema-types.ts" /> in the file where you run the makeSchema. See the PR in #348

For reference, at Cypress, we run all code in development with the equivalent of

ts-node-dev --respawn --transpileOnly

during development, and then run tsc in CI to ensure that the types are correct. We then run our production code with node -r ts-node/register/transpile-only path-to-app.ts

All 12 comments

The tsc will always be invalid until the first time you execute the TypeScript. It's a sort of chicken-and-egg problem, the code which executes to emit the types.

Try executing the script with something like ts-node-dev and then see if tsc still complains.

I test it with ts-node and tsc, and also first added plugins: [fieldAuthorizePlugin()], to schema code and after the first compile and make sure it added correct typedefs in generated files I added authorize: () => false, to my query field.
after all those steps I am still getting the error above.
also, VSCode is ok after the first compilation but the ts-node still complains.
it also works with ts-node-dev if I run it like this: ts-node-dev --respawn --transpileOnly src/app.ts
please advise.

I have the same issue... This error precisely:

Object literal may only specify known properties, and 'authorize' does not exist in type 'NexusOutputFieldConfig<"Account", "administratedProfiles">'.

I also added the plugin.

Note: My code was perfectly working with 0.11.7.

I also tested with the 14th beta. It is also working. It breaks when I upgrade to a rc.

Confirm, same issue for me on 0.12.0-rc.5

I'm working through the issues with some real world examples come up with some potential solutions / advice here, because this is a common pain point when getting started.

I just realized that because of how ts-node transpiles the code, it doesn't pick up the generated type defs file unless you explicitly reference it explicitly (via references or import). It may help if you add this explicitly, e.g. /// <reference path="./path-to-schema-types.ts" /> in the file where you run the makeSchema. See the PR in #348

For reference, at Cypress, we run all code in development with the equivalent of

ts-node-dev --respawn --transpileOnly

during development, and then run tsc in CI to ensure that the types are correct. We then run our production code with node -r ts-node/register/transpile-only path-to-app.ts

Thank you for your answer! This helps! And also, thank you for your work with nexus. It makes GraphQL so simple!

I'm working through the issues with some real world examples come up with some potential solutions / advice here, because this is a common pain point when getting started.

I just realized that because of how ts-node transpiles the code, it doesn't pick up the generated type defs file unless you explicitly reference it explicitly (via references or import). It may help if you add this explicitly, e.g. /// <reference path="./path-to-schema-types.ts" /> in the file where you run the makeSchema. See the PR in #348

For reference, at Cypress, we run all code in development with the equivalent of

ts-node-dev --respawn --transpileOnly

during development, and then run tsc in CI to ensure that the types are correct. We then run our production code with node -r ts-node/register/transpile-only path-to-app.ts

but I have same problem even with tsc, how do you pass the CI step?

Can you create a gist with your generated nexus types file, as well as the error you get with tsc?

I don't know what happened exactly but with tsc it is working now.

If anyone else is looking for an alternative solution, this helped us get our IDEs (VSCode), Jest tests and serverless-offline/serverless-typescript all working together to be authorize aware. We added this to our own custom typings since we know we will always use this plugin.

In ./typings/index.d.ts:

import { FieldAuthorizeResolver } from '@nexus/schema/dist/plugins/fieldAuthorizePlugin'

declare global {

  interface NexusGenPluginFieldConfig<TypeName extends string, FieldName extends string> {
    /**
     * Authorization for an individual field. Returning "true"
     * or "Promise<true>" means the field can be accessed.
     * Returning "false" or "Promise<false>" will respond
     * with a "Not Authorized" error for the field.
     * Returning or throwing an error will also prevent the
     * resolver from executing.
     */
    authorize?: FieldAuthorizeResolver<TypeName, FieldName>
  }
}

The in ./tsconfig.json:

{
  "compilerOptions": {
    ...,
    "typeRoots": [
      "typings",
      "./node_modules/@types"
    ],
    "types": [ 
      // Required for custom typings  if using serverless-offline & serverless-typescript:
      "../typings"
    ],
  },
}

For me none of the above solutions worked but this SO answer did: https://stackoverflow.com/a/51666714

I'm using ts-node + nodemon but maybe there's a similar option for ts-node-dev. I added --files=$PATH_TO_NEXUS_TYPEGEN to my ts-node command.

Before:

nodemon --watch 'src/**/*.ts' --ignore 'src/**/*.spec.ts' --exec 'ts-node' src/index.ts

After:

nodemon --watch 'src/**/*.ts' --ignore 'src/**/*.spec.ts' --exec 'ts-node' --files=src/generated/nexus-typegen.ts src/index.ts
                                                                           |____________________________________|
                                                                                              |
                                                                                      here's what i added

Was this page helpful?
0 / 5 - 0 ratings

Related issues

delianides picture delianides  路  6Comments

jasonkuhrt picture jasonkuhrt  路  3Comments

tonyfromundefined picture tonyfromundefined  路  3Comments

StevenLangbroek picture StevenLangbroek  路  6Comments

DregondRahl picture DregondRahl  路  3Comments