这是indexloc提供的服务,不要输入任何密码
Skip to content

[@types/pg] Generify query methods #37892

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

Merged
merged 7 commits into from
Sep 4, 2019

Conversation

HoldYourWaffle
Copy link
Contributor

Please fill in this template.

  • Use a meaningful title for the pull request. Include the name of the package modified.
  • Test the change in your own code. (Compile and run.)
  • Add or edit tests to reflect the change. (Run with npm test.)
  • Follow the advice from the readme.
  • Avoid common mistakes.
  • Run npm run lint package-name (or tsc if no tslint.json is present).

If changing an existing definition:

  • Provide a URL to documentation or source code which provides context for the suggested changes: not applicable
  • If this PR brings the type definitions up to date with a new version of the JS library, update the version number in the header. (not applicable)
  • If you are making substantial changes, consider adding a tslint.json containing { "extends": "dtslint/dt.json" }. If for reason the any rule need to be disabled, disable it for that line using // tslint:disable-next-line [ruleName] and not for whole package so that the need for disabling can be reviewed.

I generified the query methods as well as the corresponding interfaces. R will be the return type of the query, I a tuple for the parameters.

A usage example:

interface Person {
    name: string;
    naughty: boolean;
}

/* 
   The types are defined here:
   - The return type R will be the 'Person' interface defined above
   - The parameters (I for input) will be a string and boolean (in order)
*/
client.query<Person, [string, boolean]>(
    'SELECT * FROM user WHERE name = $1 AND naughty = $2',
    [ 'Johnny', true ], // this array will be typechecked
    (err, result) => console.log(result.rows[0].name) // this will now have a 'string' type
);

These additional type checks are aimed at users who have interfaces for their database types (for example auto-generated by schemats).
It is 100% opt-in and backwards compatible with the use of generic defaults added in TS 2.3.

The usefulness R parameter (for the return type) pretty much speaks for itself, it enables intellisense/typechecking without the use of annoying type assertions.

The I parameter (the inputs) might be too repetitive/over-safe for some people, which is why it comes after the (more useful) returntype generic. For my use-case I'm automatically generating parts of these method calls, and an extra sanity check is very much welcome in that case. It's also a very welcome safeguard when refactoring database types, although that probably doesn't happen too often for most people.

Because these generics are meant to check the parameters supplied directly the no-unnecessary-generics rule doesn't apply here. The dtslint page says:

Generic type parameters allow you to relate the type of one thing to another; if they are used only once, they can be replaced with their type constraint.

The emphasized part doesn't apply here, because the whole idea of these generics is to have users (optionally) manually provide an extra layer of security by specifying their own types. any is a perfectly valid type constraint here, the generics enable users to narrow it down to their own types if they so wish.

@HoldYourWaffle
Copy link
Contributor Author

It seems like pg-copy-streams has a lower minimum TS version causing the tests to fail, should I update its minimum version?

@typescript-bot typescript-bot added Popular package This PR affects a popular package (as counted by NPM download counts). The Travis CI build failed labels Aug 24, 2019
@typescript-bot
Copy link
Contributor

typescript-bot commented Aug 24, 2019

@HoldYourWaffle Thank you for submitting this PR!

🔔 @pspeter3 @fluggo @bradleyayers @mateuszkrupa @aleung @mainnika @asmarques - please review this PR in the next few days. Be sure to explicitly select Approve or Request Changes in the GitHub UI so I know what's going on.

If no reviewer appears after a week, a DefinitelyTyped maintainer will review the PR instead.

@typescript-bot
Copy link
Contributor

typescript-bot commented Aug 24, 2019

@HoldYourWaffle The Travis CI build failed! Please review the logs for more information.

Once you've pushed the fixes, the build will automatically re-run. Thanks!

@typescript-bot
Copy link
Contributor

👋 Hi there! I’ve run some quick performance metrics against master and your PR. This is still an experiment, so don’t panic if I say something crazy! I’m still learning how to interpret these metrics.

Let’s review the numbers, shall we?

Comparison details 📊
master #37892 diff
Batch compilation
Memory usage (MiB) 68.2 68.3 +0.2%
Type count 9214 9490 +3.0%
Assignability cache size 3050 3087 +1.2%
Subtype cache size 42 45 +7.1%
Identity cache size 1 1 0.0%
Language service
Samples taken 374 390 +4.3%
Identifiers in tests 374 390 +4.3%
getCompletionsAtPosition
    Mean duration (ms) 373.4 379.0 +1.5%
    Median duration (ms) 371.3 378.7 +2.0%
    Mean CV 13.3% 13.2% -0.9%
    Worst duration (ms) 470.1 481.5 +2.4%
    Worst identifier res Person
getQuickInfoAtPosition
    Mean duration (ms) 389.7 399.3 +2.5%
    Median duration (ms) 385.9 398.5 +3.3%
    Mean CV 13.8% 13.6% -1.3%
    Worst duration (ms) 520.2 507.1 -2.5%
    Worst identifier stack query

It looks like nothing changed too much. I’m pretty lenient since I’m still an experiment, so take a look anyways and make sure nothing looks out of place.


If you have any questions or comments about me, you can ping @andrewbranch. Have a nice day!

Copy link
Contributor

@pspeter3 pspeter3 left a comment

Choose a reason for hiding this comment

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

How does this relate to #37689?

@HoldYourWaffle
Copy link
Contributor Author

Seems like #37689 is a reduced implementation of this since it only types the return value. I'm not 100% sure what the additional RowBase interface is supposed to be though.

Interesting to see that someone had this idea too. I've had this changes running in production for a while now, I honestly just forgot to send a PR out 😅

@inad9300
Copy link
Contributor

RowBase was there to constraint the generic types you can pass around. For instance, we can tell at compile time that query<number>(...) is a bug, as no SQL query can be written in the context of pg that results in a number (nor an array of numbers) being returned.

@HoldYourWaffle
Copy link
Contributor Author

That makes a lot of sense, I'll incorporate something similar in this PR.
Would it make sense to add a similar constraint type to the I generic?

@inad9300
Copy link
Contributor

inad9300 commented Aug 27, 2019

I believe that for I is enough with enforcing that it must extend any[]. You could possibly go further and say something like extends (null | boolean | number | string | Date | Uint8Array)[] or such, but you never know which types might be returned by the query() methods due to node-postgres' support for custom parsers.

Edit On a second thought, I don't see the value on having the I generic type: embedded SQL queries are unsafe on themselves (i.e. the types provided for the values aren't going to be verified against those supported by the query); and the types can't be defined once and used for multiple sets of values either, I believe, which makes the type declaration quite redundant. It feels to me as saying let s: string = '' (as opposed to just let s = '') when you are never going to use s again. Could you please try to elaborate on why you think I could be useful?

@HoldYourWaffle
Copy link
Contributor Author

but you never know which types might be returned by the query() methods due to node-postgres' support for custom parsers.

I'm not sure what the return type of query has to do with I, I is for the input parameters.

and the types can't be defined once and used for multiple sets of values either, I believe, which makes the type declaration quite redundant.

I'm not sure what you mean by this, could you clarify? What do you want to re-use?


It feels to me as saying let s: string = '' (as opposed to just let s = '') and never using s. Could you please try to elaborate on why you think I could be useful?

In a way it's definitely like let s: string = ''. I already put my rationale for adding it in my original post:

The I parameter (the inputs) might be too repetitive/over-safe for some people, which is why it comes after the (more useful) returntype generic.
For my use-case I'm automatically generating parts of these method calls, and an extra sanity check is very much welcome in that case.
It's also a very welcome safeguard when refactoring database types, although that probably doesn't happen too often for most people.

To elaborate on my use-case, I have a setup where database type definitions are generated for me. So I'm writing my queries like this:

await database.query<void, [UserFields.id]>(
    'UPDATE "user" SET date_last_seen = now() WHERE id=$1',
    [ user.id ]
);

As you see I'm not literally reusing the same type twice. The user variable could come from anywhere and its internal representation might differ from the database, this is where the extra type-check comes in handy.
This is of course a very simple example, but it's enough to demonstrate my use-case.
I recognize that not everyone will find this extra check useful, which is why it's 100% opt-in. Embedded SQL queries indeed inherently type-unsafe, but with this extra check hopefully a little less so.

@inad9300
Copy link
Contributor

I'm not sure what the return type of query has to do with I, I is for the input parameters.

I intended to refer to custom serializers, as opposed to parsers. Sorry for the confusion.

I'm not sure what you mean by this, could you clarify? What do you want to re-use?

If you could somehow declare the types of the values once and have them checked against multiple sets of values, I thought that would somehow be a possible justification for declaring them, but it doesn't seem to be the case. To illustrate what I meant, see the following example which allows exactly that, although through an extra function:

// Types declared once
function getSomething(values: [string, number]) {
  pg.query(`select * from something where s = $1 and n = $2`, values)
}

// Type-checking performed multiple times
getSomething(['0', 0])
getSomething(['1', 1])

To elaborate on my use-case (...)

Thanks for the additional explanation. I still find it somewhat weird to specify the types of your own input, over which you have complete control. But I'm fine with the change.

@HoldYourWaffle
Copy link
Contributor Author

Thanks for the additional explanation. I still find it somewhat weird to specify the types of your own input, over which you have complete control.

But I'm fine with the change.

That's great to hear 😄 I think the bot wants you to push some approve button somewhere in that case.
In the meantime, how should I handle the travis failure? Should I raise the minimum typescript version for pg-copy-streams?

@HoldYourWaffle
Copy link
Contributor Author

@pspeter3 What do you think of these changes?

@inad9300 Can you double check for me if I implemented your RowBase-like constraint correctly?

@typescript-bot
Copy link
Contributor

Updated numbers for you here from 033bac5:

Comparison details 📊
master #37892 diff
Batch compilation
Memory usage (MiB) 68.9 64.2 -6.9%
Type count 9214 9491 +3.0%
Assignability cache size 3050 3090 +1.3%
Subtype cache size 42 45 +7.1%
Identity cache size 1 1 0.0%
Language service
Samples taken 374 390 +4.3%
Identifiers in tests 374 390 +4.3%
getCompletionsAtPosition
    Mean duration (ms) 363.1 364.8 +0.5%
    Median duration (ms) 361.4 364.1 +0.7%
    Mean CV 13.8% 12.4% -9.7%
    Worst duration (ms) 475.1 465.7 -2.0%
    Worst identifier res fields
getQuickInfoAtPosition
    Mean duration (ms) 382.2 383.0 +0.2%
    Median duration (ms) 380.5 380.7 +0.1%
    Mean CV 14.2% 13.3% -6.4%
    Worst duration (ms) 504.3 488.3 -3.2%
    Worst identifier err err

It looks like nothing changed too much. I’m pretty lenient since I’m still an experiment, so take a look anyways and make sure nothing looks out of place.

@typescript-bot
Copy link
Contributor

typescript-bot commented Aug 29, 2019

@HoldYourWaffle The Travis CI build failed! Please review the logs for more information.

Once you've pushed the fixes, the build will automatically re-run. Thanks!

@inad9300
Copy link
Contributor

inad9300 commented Aug 30, 2019

QueryResultRow should be applied to QueryResult and not to QueryResultArray, as the latter represents (mostly) a matrix of primitives, and QueryResultRow models a key-value structure. As a basic check that the code is correct, I believe the expression extends QueryResultRow[] should appear nowhere in the code.

@typescript-bot typescript-bot added the Other Approved This PR was reviewed and signed-off by a community member. label Aug 30, 2019
`R` will be the return type of the query, `I` a tuple for parameters
@HoldYourWaffle
Copy link
Contributor Author

Whoops that's a pretty dumb mistake, no idea how I missed that. I think I've fixed it now, but it's too early for me to tell...

@typescript-bot
Copy link
Contributor

Updated numbers for you here from e91f271:

Comparison details 📊
master #37892 diff
Batch compilation
Memory usage (MiB) 63.8 61.6 -3.4%
Type count 9230 9496 +2.9%
Assignability cache size 3050 3094 +1.4%
Subtype cache size 42 45 +7.1%
Identity cache size 1 1 0.0%
Language service
Samples taken 374 390 +4.3%
Identifiers in tests 374 390 +4.3%
getCompletionsAtPosition
    Mean duration (ms) 352.6 354.2 +0.5%
    Median duration (ms) 351.3 351.3 0.0%
    Mean CV 14.7% 14.1% -4.0%
    Worst duration (ms) 432.0 462.4 +7.0%
    Worst identifier console err
getQuickInfoAtPosition
    Mean duration (ms) 370.0 371.8 +0.5%
    Median duration (ms) 370.4 368.3 -0.6%
    Mean CV 15.7% 15.1% -4.1%
    Worst duration (ms) 496.9 488.4 -1.7%
    Worst identifier e err

It looks like nothing changed too much. I’m pretty lenient since I’m still an experiment, so take a look anyways and make sure nothing looks out of place.

@typescript-bot
Copy link
Contributor

typescript-bot commented Aug 30, 2019

@HoldYourWaffle The Travis CI build failed! Please review the logs for more information.

Once you've pushed the fixes, the build will automatically re-run. Thanks!

@HoldYourWaffle
Copy link
Contributor Author

@inad9300 I have addressed your concerns.

I have also updated the minimum typescript version for @types/pg-copy-streams to avoid travis failing.

@typescript-bot
Copy link
Contributor

typescript-bot commented Sep 2, 2019

@HoldYourWaffle The Travis CI build failed! Please review the logs for more information.

Once you've pushed the fixes, the build will automatically re-run. Thanks!

@typescript-bot
Copy link
Contributor

Updated numbers for you here from 8db1e4b:

pg-copy-streams/v1

Comparison details for pg-copy-streams/v1 📊
master #37892 diff
Batch compilation
Memory usage (MiB) 64.2 67.5 +5.2%
Type count 9054 9175 +1.3%
Assignability cache size 2998 3024 +0.9%
Subtype cache size 3 3 0.0%
Identity cache size 1 1 0.0%
Language service
Samples taken 26 26 0.0%
Identifiers in tests 26 26 0.0%
getCompletionsAtPosition
    Mean duration (ms) 372.5 374.9 +0.7%
    Median duration (ms) 375.1 371.9 -0.9%
    Mean CV 13.4% 12.2% -9.1%
    Worst duration (ms) 430.5 450.6 +4.7%
    Worst identifier query to
getQuickInfoAtPosition
    Mean duration (ms) 394.5 395.5 +0.3%
    Median duration (ms) 393.4 390.3 -0.8%
    Mean CV 16.3% 14.9% -8.8%
    Worst duration (ms) 458.3 493.7 +7.7%
    Worst identifier query query

It looks like nothing changed too much. I’m pretty lenient since I’m still an experiment, so take a look anyways and make sure nothing looks out of place.

pg-ears/v1

Comparison details for pg-ears/v1 📊
master #37892 diff
Batch compilation
Memory usage (MiB) 64.0 61.8 -3.5%
Type count 9013 9122 +1.2%
Assignability cache size 2989 3015 +0.9%
Subtype cache size 0 0
Identity cache size 1 1 0.0%
Language service
Samples taken 10 10 0.0%
Identifiers in tests 10 10 0.0%
getCompletionsAtPosition
    Mean duration (ms) 393.4 378.2 -3.9%
    Median duration (ms) 395.5 380.0 -3.9%
    Mean CV 17.4% 15.9% -8.7%
    Worst duration (ms) 427.0 410.1 -4.0%
    Worst identifier password password
getQuickInfoAtPosition
    Mean duration (ms) 387.3 366.1 -5.5%
    Median duration (ms) 388.3 368.6 -5.1%
    Mean CV 12.1% 13.3% +10.2%
    Worst duration (ms) 413.5 386.5 -6.5%
    Worst identifier pgEars password

It looks like nothing changed too much. I’m pretty lenient since I’m still an experiment, so take a look anyways and make sure nothing looks out of place.

pg-large-object/v2

Comparison details for pg-large-object/v2 📊
master #37892 diff
Batch compilation
Memory usage (MiB) 61.3 61.8 +0.7%
Type count 9121 9230 +1.2%
Assignability cache size 3013 3039 +0.9%
Subtype cache size 0 0
Identity cache size 1 1 0.0%
Language service
Samples taken 161 161 0.0%
Identifiers in tests 161 161 0.0%
getCompletionsAtPosition
    Mean duration (ms) 370.9 389.5 +5.0%
    Median duration (ms) 368.0 382.2 +3.9%
    Mean CV 15.5% 14.2% -8.9%
    Worst duration (ms) 514.1 558.4 +8.6%
    Worst identifier pg SEEK_SET
getQuickInfoAtPosition
    Mean duration (ms) 349.4 388.9 +11.3%
    Median duration (ms) 345.0 381.3 +10.5%
    Mean CV 14.6% 15.5% +5.9%
    Worst duration (ms) 508.7 515.6 +1.4%
    Worst identifier bufferSize close

It looks like nothing changed too much. I’m pretty lenient since I’m still an experiment, so take a look anyways and make sure nothing looks out of place.

pg/v7

Comparison details for pg/v7 📊
master #37892 diff
Batch compilation
Memory usage (MiB) 63.5 69.2 +8.9%
Type count 9230 9506 +3.0%
Assignability cache size 3050 3097 +1.5%
Subtype cache size 42 45 +7.1%
Identity cache size 1 1 0.0%
Language service
Samples taken 374 390 +4.3%
Identifiers in tests 374 390 +4.3%
getCompletionsAtPosition
    Mean duration (ms) 382.4 363.0 -5.1%
    Median duration (ms) 379.4 359.8 -5.2%
    Mean CV 15.1% 15.0% -0.9%
    Worst duration (ms) 479.6 458.2 -4.5%
    Worst identifier name err
getQuickInfoAtPosition
    Mean duration (ms) 394.6 364.9 -7.5%
    Median duration (ms) 391.5 360.1 -8.0%
    Mean CV 15.5% 14.6% -5.8%
    Worst duration (ms) 506.5 485.4 -4.2%
    Worst identifier err err

It looks like nothing changed too much. I’m pretty lenient since I’m still an experiment, so take a look anyways and make sure nothing looks out of place.

@typescript-bot
Copy link
Contributor

Updated numbers for you here from 479677f:

pg-copy-streams/v1

Comparison details for pg-copy-streams/v1 📊
master #37892 diff
Batch compilation
Memory usage (MiB) 67.1 65.5 -2.4%
Type count 9054 9175 +1.3%
Assignability cache size 2998 3024 +0.9%
Subtype cache size 3 3 0.0%
Identity cache size 1 1 0.0%
Language service
Samples taken 26 26 0.0%
Identifiers in tests 26 26 0.0%
getCompletionsAtPosition
    Mean duration (ms) 366.8 369.3 +0.7%
    Median duration (ms) 361.9 372.5 +2.9%
    Mean CV 10.6% 13.2% +23.8%
    Worst duration (ms) 417.8 420.5 +0.6%
    Worst identifier query query
getQuickInfoAtPosition
    Mean duration (ms) 386.0 382.0 -1.0%
    Median duration (ms) 382.7 388.0 +1.4%
    Mean CV 16.4% 14.7% -10.6%
    Worst duration (ms) 461.5 426.1 -7.7%
    Worst identifier to query

It looks like nothing changed too much. I’m pretty lenient since I’m still an experiment, so take a look anyways and make sure nothing looks out of place.

pg-ears/v1

Comparison details for pg-ears/v1 📊
master #37892 diff
Batch compilation
Memory usage (MiB) 60.6 60.9 +0.6%
Type count 9013 9122 +1.2%
Assignability cache size 2989 3015 +0.9%
Subtype cache size 0 0
Identity cache size 1 1 0.0%
Language service
Samples taken 10 10 0.0%
Identifiers in tests 10 10 0.0%
getCompletionsAtPosition
    Mean duration (ms) 365.1 365.3 0.0%
    Median duration (ms) 367.1 375.5 +2.3%
    Mean CV 12.9% 14.3% +10.9%
    Worst duration (ms) 425.8 400.1 -6.0%
    Worst identifier user user
getQuickInfoAtPosition
    Mean duration (ms) 389.6 380.3 -2.4%
    Median duration (ms) 393.7 384.4 -2.4%
    Mean CV 14.8% 11.5% -22.3%
    Worst duration (ms) 441.5 408.3 -7.5%
    Worst identifier password host

It looks like nothing changed too much. I’m pretty lenient since I’m still an experiment, so take a look anyways and make sure nothing looks out of place.

pg-large-object/v2

Comparison details for pg-large-object/v2 📊
master #37892 diff
Batch compilation
Memory usage (MiB) 62.8 66.8 +6.3%
Type count 9121 9230 +1.2%
Assignability cache size 3013 3039 +0.9%
Subtype cache size 0 0
Identity cache size 1 1 0.0%
Language service
Samples taken 161 161 0.0%
Identifiers in tests 161 161 0.0%
getCompletionsAtPosition
    Mean duration (ms) 365.9 367.1 +0.3%
    Median duration (ms) 358.4 364.2 +1.6%
    Mean CV 14.2% 14.1% -0.4%
    Worst duration (ms) 514.0 455.6 -11.3%
    Worst identifier length truncateAsync
getQuickInfoAtPosition
    Mean duration (ms) 361.3 363.4 +0.6%
    Median duration (ms) 352.9 362.6 +2.7%
    Mean CV 12.9% 13.9% +8.0%
    Worst duration (ms) 524.0 437.5 -16.5%
    Worst identifier bufferSize Buffer

It looks like nothing changed too much. I’m pretty lenient since I’m still an experiment, so take a look anyways and make sure nothing looks out of place.

pg-pool/v2

Comparison details for pg-pool/v2 📊
master #37892 diff
Batch compilation
Memory usage (MiB) 63.8 62.6 -2.0%
Type count 8421 8598 +2.1%
Assignability cache size 904 938 +3.8%
Subtype cache size 7 6 -14.3%
Identity cache size 0 0
Language service
Samples taken 82 82 0.0%
Identifiers in tests 82 82 0.0%
getCompletionsAtPosition
    Mean duration (ms) 364.7 369.8 +1.4%
    Median duration (ms) 359.1 369.5 +2.9%
    Mean CV 13.6% 13.6% -0.2%
    Worst duration (ms) 461.1 429.9 -6.8%
    Worst identifier port end
getQuickInfoAtPosition
    Mean duration (ms) 388.1 388.7 +0.1%
    Median duration (ms) 383.2 388.1 +1.3%
    Mean CV 14.7% 15.3% +4.3%
    Worst duration (ms) 468.9 463.7 -1.1%
    Worst identifier min pool

It looks like nothing changed too much. I’m pretty lenient since I’m still an experiment, so take a look anyways and make sure nothing looks out of place.

pg-query-stream/v1

Comparison details for pg-query-stream/v1 📊
master #37892 diff
Batch compilation
Memory usage (MiB) 62.0 61.4 -0.8%
Type count 9033 9154 +1.3%
Assignability cache size 3000 3026 +0.9%
Subtype cache size 4 4 0.0%
Identity cache size 1 1 0.0%
Language service
Samples taken 34 34 0.0%
Identifiers in tests 34 34 0.0%
getCompletionsAtPosition
    Mean duration (ms) 364.3 364.4 +0.1%
    Median duration (ms) 359.8 349.9 -2.8%
    Mean CV 16.6% 14.5% -12.6%
    Worst duration (ms) 430.8 460.5 +6.9%
    Worst identifier done on
getQuickInfoAtPosition
    Mean duration (ms) 401.9 389.9 -3.0%
    Median duration (ms) 390.2 388.6 -0.4%
    Mean CV 18.7% 16.0% -14.6%
    Worst duration (ms) 515.1 467.5 -9.2%
    Worst identifier client stream

It looks like nothing changed too much. I’m pretty lenient since I’m still an experiment, so take a look anyways and make sure nothing looks out of place.

pg/v7

Comparison details for pg/v7 📊
master #37892 diff
Batch compilation
Memory usage (MiB) 63.6 65.9 +3.7%
Type count 9230 9506 +3.0%
Assignability cache size 3050 3097 +1.5%
Subtype cache size 42 45 +7.1%
Identity cache size 1 1 0.0%
Language service
Samples taken 374 390 +4.3%
Identifiers in tests 374 390 +4.3%
getCompletionsAtPosition
    Mean duration (ms) 362.2 368.6 +1.8%
    Median duration (ms) 358.2 367.0 +2.4%
    Mean CV 13.6% 13.3% -2.7%
    Worst duration (ms) 453.5 477.8 +5.4%
    Worst identifier rows end
getQuickInfoAtPosition
    Mean duration (ms) 377.5 382.4 +1.3%
    Median duration (ms) 373.6 380.3 +1.8%
    Mean CV 13.9% 13.3% -4.2%
    Worst duration (ms) 481.2 496.8 +3.2%
    Worst identifier error stack

It looks like nothing changed too much. I’m pretty lenient since I’m still an experiment, so take a look anyways and make sure nothing looks out of place.

@HoldYourWaffle
Copy link
Contributor Author

Finally got travis to pass.
@inad9300 I think the only thing left now is for you to press some kind of "approve" button somewhere

Copy link
Contributor

@mainnika mainnika left a comment

Choose a reason for hiding this comment

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

in general, it's a good PR 👍🏻
pg-pool is ok about these changes.

@typescript-bot typescript-bot added Owner Approved A listed owner of this package signed off on the pull request. Merge:Express and removed Awaiting reviewer feedback labels Sep 2, 2019
@typescript-bot
Copy link
Contributor

A definition owner has approved this PR ⭐️. A maintainer will merge this PR shortly. If it shouldn't be merged yet, please leave a comment saying so and we'll wait. Thank you for your contribution to DefinitelyTyped!

@rbuckton rbuckton merged commit 47e9cf6 into DefinitelyTyped:master Sep 4, 2019
@rbuckton
Copy link
Collaborator

rbuckton commented Sep 4, 2019

Thanks for the contribution!

@typescript-bot
Copy link
Contributor

I just published @types/pg@7.11.1 to npm.

@typescript-bot
Copy link
Contributor

I just published @types/pg-ears@1.0.1 to npm.

@typescript-bot
Copy link
Contributor

I just published @types/pg-pool@2.0.1 to npm.

@HoldYourWaffle HoldYourWaffle deleted the pg-generify-query branch September 4, 2019 18:58
@WojasKrk
Copy link

WojasKrk commented May 3, 2024

Please fill in this template.

  • Use a meaningful title for the pull request. Include the name of the package modified.
  • Test the change in your own code. (Compile and run.)
  • Add or edit tests to reflect the change. (Run with npm test.)
  • Follow the advice from the readme.
  • Avoid common mistakes.
  • Run npm run lint package-name (or tsc if no tslint.json is present).

If changing an existing definition:

  • Provide a URL to documentation or source code which provides context for the suggested changes: not applicable
  • If this PR brings the type definitions up to date with a new version of the JS library, update the version number in the header. (not applicable)
  • If you are making substantial changes, consider adding a tslint.json containing { "extends": "dtslint/dt.json" }. If for reason the any rule need to be disabled, disable it for that line using // tslint:disable-next-line [ruleName] and not for whole package so that the need for disabling can be reviewed.

I generified the query methods as well as the corresponding interfaces. R will be the return type of the query, I a tuple for the parameters.

A usage example:

interface Person {
    name: string;
    naughty: boolean;
}

/* 
   The types are defined here:
   - The return type R will be the 'Person' interface defined above
   - The parameters (I for input) will be a string and boolean (in order)
*/
client.query<Person, [string, boolean]>(
    'SELECT * FROM user WHERE name = $1 AND naughty = $2',
    [ 'Johnny', true ], // this array will be typechecked
    (err, result) => console.log(result.rows[0].name) // this will now have a 'string' type
);

These additional type checks are aimed at users who have interfaces for their database types (for example auto-generated by schemats).
It is 100% opt-in and backwards compatible with the use of generic defaults added in TS 2.3.

The usefulness R parameter (for the return type) pretty much speaks for itself, it enables intellisense/typechecking without the use of annoying type assertions.

The I parameter (the inputs) might be too repetitive/over-safe for some people, which is why it comes after the (more useful) returntype generic. For my use-case I'm automatically generating parts of these method calls, and an extra sanity check is very much welcome in that case. It's also a very welcome safeguard when refactoring database types, although that probably doesn't happen too often for most people.

Because these generics are meant to check the parameters supplied directly the no-unnecessary-generics rule doesn't apply here. The dtslint page says:

Generic type parameters allow you to relate the type of one thing to another; if they are used only once, they can be replaced with their type constraint.

The emphasized part doesn't apply here, because the whole idea of these generics is to have users (optionally) manually provide an extra layer of security by specifying their own types. any is a perfectly valid type constraint here, the generics enable users to narrow it down to their own types if they so wish.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Other Approved This PR was reviewed and signed-off by a community member. Owner Approved A listed owner of this package signed off on the pull request. Popular package This PR affects a popular package (as counted by NPM download counts).
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants