Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add typing for RawBinding and ValueMap #3036

Closed
wants to merge 2 commits into from
Closed

Add typing for RawBinding and ValueMap #3036

wants to merge 2 commits into from

Conversation

cham11ng
Copy link
Contributor

@cham11ng cham11ng commented Feb 6, 2019

Add typing for RawBinding and ValueMap

This was the error I was facing. Since, its type was not exported I had to include it in my codebase.

[ts]
Argument of type 'object' is not assignable to parameter of type '(string | number | boolean | Raw | QueryBuilder | string[] | number[] | Date | Date[] | boolean[] | Buffer)[] | ValueMap'.
  Type 'object' is not assignable to type 'ValueMap'.
    Index signature is missing in type '{}'. [2345]
(parameter) params: object

I've added RawBinding and ValueMap.

@arenddeboer
Copy link

Merging this would be highly appreciated!

@kibertoad
Copy link
Collaborator

@arenddeboer Could you please test updated binding locally to confirm they are indeed correct? I am not familiar enough with this part to merge this confidently.

types/knex.d.ts Outdated
interface RawQueryBuilder {
(sql: string, ...bindings: (Value | QueryBuilder)[]): QueryBuilder;
(sql: string, bindings: (Value | QueryBuilder)[] | ValueMap): QueryBuilder;
(sql: string, ...bindings: RawBinding): QueryBuilder;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can understand RawBinding being added, but aren't Value and QueryBuilder valid params as well? Shouldn't they be also kept?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, I see no need to remove them.

@arenddeboer
Copy link

@kibertoad I have tested the pull request as is and this indeed solves the issue with the bindings.
I'm no expert on TypeScript though, so if anyone else can comment on this please do.

@kibertoad
Copy link
Collaborator

@arenddeboer Wait, I only now noticed - does this PR even do anything? Isn't RawBinding that it add is exactly same thing as (Value | QueryBuilder)[] that it replaces?

@arenddeboer
Copy link

Sorry for the delay.
The main problem for me was being unable to pass a bindings object, because ValueMap is an non-exported type. Making it an interface under the Knex namespace allows us to do something like:

// index.d.ts inside namespace Knex 
interface ValueMap {
    [key: string]: Value | Knex.QueryBuilder | undefined;
  }
// custom code.ts:
/** knex js bindings for my query */
    interface IBindings extends ValueMap {
      siteId: number;
      languageId: number;
      country?: string;
    }
    const bindings: IBindings = 
      siteId,
      languageId,
    };
knex.raw(myQuery, bindings)

So to get bindings working like this, one does not have to change RawBinding But I do not know which other problems @cham11ng ran into to warrant the other changes.

@elhigu
Copy link
Member

elhigu commented Mar 19, 2019

This makes me wonder... now that we have typings in knex repo it would be possible to actually write tests for typings. Not saying that it needs to be done in this PR.

@arenddeboer
Copy link

I agree and was considering mentioning this in my last reply. Not sure what the best way forward is for Typescript tests though, but it makes a lot of sense and would probably help reason about current and future changes.

@kibertoad
Copy link
Collaborator

@lorefnon Could you please take a look if this change still makes sense after all the latest changes?

@lorefnon
Copy link
Collaborator

The only change here is that RawBinding and ValueMap (now ValueDict) are being exposed. Remaining changes are no-op.

I may not have the full clarity here, but I don't think this is (and ever was) very useful because typescript's inference should have done the right thing (even with the bindings we had before). It is likely that in the application there is somewhere an explicit type annotation (as object) causing it to fail which can be removed.

For example:

const bindings: object = {id: 1};

knex.raw('select * from "users" where "id" = ?', bindings);
// This fails because object is not assignable to ValueMap.

But simply removing that type annotation, will fix this:

const bindings = {id: 1};

knex.raw('select * from "users" where "id" = ?', bindings); 
// { id: number } is implicitly assignable to ValueMap

Nevertheless, if this makes someone's life simpler I can rebase this change against current master.

@kibertoad
Copy link
Collaborator

@lorefnon No need to rebase per se, probably would be much easier to just do sensible changes separately. Just exposing ValueDict seems like a reasonable change to allow people type their code more explicitly (otherwise they would need to introduce some local types that would then duck-type to ValueDict on compilation). If you are still doing any changes to typings, could you include that part?

@lorefnon
Copy link
Collaborator

As per #3036 (comment) I have exposed this and some other utility types in #3211.

@cham11ng I am adding you as a co-author in this PR so your contribution wouldn't get lost. Please let me know if you are not ok with this.

@cham11ng
Copy link
Contributor Author

@lorefnon It's okay

kibertoad pushed a commit that referenced this pull request May 19, 2019
Ref: #3036 (comment)

Co-authored-by: Sagar Chamling <sgr.raee@gmail.com>
@kibertoad
Copy link
Collaborator

Closing this in favour of #3211

@kibertoad kibertoad closed this May 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants