-
Notifications
You must be signed in to change notification settings - Fork 128
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
TS typing for Dataframe #2382
TS typing for Dataframe #2382
Conversation
Codecov Report
@@ Coverage Diff @@
## main #2382 +/- ##
=======================================
Coverage 68.23% 68.23%
=======================================
Files 127 127
Lines 12259 12259
=======================================
Hits 8365 8365
Misses 3894 3894
Flags with carried forward coverage won't be shown. Click here to find out more. Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!! Thanks for the massive PR, Bruce 🤩 👏 !! This looks amazing!
Just a few nits I could find 😆 Thanks again!
@@ -141,17 +163,13 @@ class Dataframe { | |||
Object.freeze(this); | |||
} | |||
|
|||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types --- FIXME: disabled temporarily on migrate to TS. | |||
/** @internal */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ayyy @internal 🔥 !!
return offset >= 0 && offset < length; | ||
const has = function has(rlabel: LabelType) { | ||
const offset = getRowOffset(rlabel); | ||
return offset !== undefined && offset >= 0 && offset < length; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
super nit: do we need to check offset !== undefined
if getRowOffset()
always returns a number?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch - that is a BUG!!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hurray! Do we need code change here? It seems to still be offset !== undefined && offset >= 0 && offset <
😆
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only because the comment refers to the outdated code. Take a look at the most recent commit to the PR, not the obsolete commit :-)
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any -- - FIXME: disabled temporarily on migrate to TS. | ||
isubsetMask(rowMask: any, colMask = null, withRowIndex = null) { | ||
isubsetMask( | ||
rowMask: Uint8Array | boolean[] | null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!! Types are so helpful here 🤩 👏
return Number.isInteger(i) && i >= 0 && i < this.maxOffset ? i : undefined; | ||
return Number.isInteger(offset) && offset >= 0 && offset < this.maxOffset | ||
? offset | ||
: undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does it make sense to return -1
instead of undefined
here to have consistency with getOffset()
above ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it doesn't. -1 is a legal label.
Remember:
- offsets are numeric indices.
-1
is "no such offset" - labels are any string|bool|number.
undefined
is "no such label"
This is documented in the comments for getOffset()
and getLabel()
What makes this particular class confusing is that it is the identity label index (aka offset===label).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ooh got it! Thanks for the explanation 🎉 Makes sense to me now 😄 !
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS. | ||
return arr.map((i: any) => this.getLabel(i)); | ||
this.getLabel = function getLabel(offset: number) { | ||
return Number.isInteger(offset) ? labels[offset] : undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same question here for undefined
vs. -1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same answer as above. See the abstract method definition.
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- FIXME: disabled temporarily on migrate to TS. | ||
return arr.map((i: any) => this.getLabel(i)); | ||
this.getLabel = function getLabel(offset: number) { | ||
return Number.isInteger(offset) ? rindex[offset] : undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same question here for undefined
vs. -1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same answer as above. See the abstract method definition.
client/src/util/dataframe/types.ts
Outdated
} | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-explicit-any --- a legitimate use of any. | ||
export type AnyFunction<T = unknown> = (...args: any[]) => T; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just curious if unknown[]
would work here instead of any[]
?
https://blog.logrocket.com/when-to-use-never-and-unknown-in-typescript-5e4d6c5799ad/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it won't work as you can't call the memoized function without a type error. See, for example, how TS defines the signatures to Function.call, Function.bind, etc.
What would be better is to improve the type pass through for the memoize() function, which is the only user of this type. I'll fix that for both memoize() and callOnceLazy().
Eg,
export function memoize<
T extends (...args: any[]) => any = (...args: any[]) => any
>(
fn: T,
hashFn: (...args: Parameters<T>) => string,
maxResultsCached = -1
): (...args: Parameters<T>) => ReturnType<T> {
...
}
Side note: fixing this pointed out a small typing bug! Yay.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ps. if you haven't already done so, it is worth studying the type signatures for stuff like Function.bind, Function.apply, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh didn't think of checking out those signatures! Thanks for the tip 👍
Using Parameters<T>
SGTM!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks Bruce!
This reverts commit 45cecad.
This PR includes:
Notable API changes:
This is another partial fix for #2366