Search code examples
node.jspostgresqltypescriptknex.jsobjection.js

Node js + Objection js + Postgresql. Argument of type '{ token: string }' is not assignable to parameter of type 'PartialUpdate<User>'


Environment:

  1. node js
  2. ES6
  3. knex: ^0.16.3
  4. objection: ^1.5.3
  5. pg: ^7.8.0 ~ postgresql

Problem:

I can't update user token in the database. I get an error message from typescript.

Typescript error message:

Argument of type '{ token: string; }' is not assignable to parameter of type 'PartialUpdate<User>'. Object literal may only specify known properties, and 'token' does not exist in type 'PartialUpdate<User>'.

Problem method

If I write @ts-ignore, the method will work, but I can't understand.

Why does it give me an error?

import { User } from '@database/models';

...
const setToken = async (id: any, token: string) => {
  try {
    await transaction(User.knex(), trx =>
      User.query(trx)
      // An error appears on this line
        .update({ token })
        .where({ id }),
    );
  } catch (e) {
    throw e;
  }
};

My user model

'use strict';

import { Model } from 'objection';

export default class User extends Model {
  static get tableName() {
    return 'users';
  }

  static get jsonSchema() {
    return {
      type: 'object',

      properties: {
        id: { type: 'uuid' },
        full_name: { type: 'string', minLength: 1, maxLength: 255 },
        email: { type: 'string', minLength: 1, maxLength: 255 },
        avatar: { type: 'string' },
        provider_data: {
          type: 'object',
          properties: {
            uid: { type: 'string' },
            provider: { type: 'string' },
          },
        },
        token: { type: 'string' },
        created_at: { type: 'timestamp' },
        updated_at: { type: 'timestamp' },
      },
    };
  }
}

Solution

  • The problem was that I did not define the types of variables in my model. An example from the official library that gave me know about what I did wrong - https://github.com/Vincit/objection.js/tree/master/examples/express-ts

    Updated model

    export default class User extends Model {
      readonly id!: v4;
      full_name?: string;
      email?: string;
      avatar?: string;
      provider_data?: {
        uid: string;
        provider: string;
      };
      token?: string;
    
      static tableName = 'users';
    
      static jsonSchema = {
        type: 'object',
    
        properties: {
          id: { type: 'uuid' },
          full_name: { type: 'string', minLength: 1, maxLength: 255 },
          email: { type: 'string', minLength: 1, maxLength: 255 },
          avatar: { type: 'string' },
          provider_data: {
            type: 'object',
            properties: {
              uid: { type: 'string' },
              provider: { type: 'string' },
            },
          },
          token: { type: 'string' },
          created_at: { type: 'timestamp' },
          updated_at: { type: 'timestamp' },
        },
      };
    }
    

    Updated method

    const setToken = async (id: any, token: string) => {
      try {
        User.query()
          .update({ token })
          .where({ id });
      } catch (e) {
        throw e;
      }
    };