-
Notifications
You must be signed in to change notification settings - Fork 164
feat: add type declarations #193
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
Conversation
For the types to be picked by TS, "main": "lib/index.js",
"module": "es/index.js",
+ "types": "dist/index.d.ts", Relevant PR: #86 If it helps, here are some typings we've got in one of our projects. It's a very modest starting point, but free to reuse any this code in your diff 🙂
declare module "react-base-table" {
export interface RowExpandEvent {
expanded: boolean
rowData: {
id: string
parentId?: string
} & { [key: string]: any }
rowIndex: number
rowKey: string
}
export interface ExpandIconBaseProps {
expandable: boolean
expanded: boolean
depth?: number
onExpand: (expanded: boolean) => void
}
export const unflatten: any
const Table: any
export default Table
export interface BaseColumnInfo {
key: string
width: number
}
export interface FrozenColumnInfo extends BaseColumnInfo {
frozen: true
label: string
}
} |
types/index.d.ts
Outdated
/** | ||
* The key field of each data item | ||
*/ | ||
rowKey?: string | 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.
type RowKey = string | 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.
isn't rowKey optional?
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.
I think @nihgwu is suggesting to create a new separate type and then use it here as
rowKey?: RowKey
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.
ah ok yea i can do that.
types/index.d.ts
Outdated
/** | ||
* Custom renderer on top of the table component | ||
*/ | ||
overlayRenderer?: React.ReactNode | (() => React.ReactNode); |
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.
maybe we could have a type CallOrReturn<T, P = {}> = T | ((p?: P, ...rest: any[]) => T)
? I'm learning TS, not sure if thats the correct way
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.
looks like this type is better type CallOrReturn<T, P = any[]> = T | (P extends any[] ? ((...p: P) => T) : ((p: P) => 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.
@jamesonhill WDYT or it's not intuitive?
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.
It can definitely make some of the typings cleaner. It would be used for any props where the current typings are someType | () => someType
?
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.
yes, and more, like CallOrReturn<React.ReactNode>
and CallOrReturn<React.ReactNode, Args>
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.
I think i covered all of those types of instances in the changes i just pushed.
types/index.d.ts
Outdated
* A callback function for the header cell click event | ||
* The handler is of the shape of `({ column, key, order }) => *` | ||
*/ | ||
onColumnSort?: ({ column, key, order }: SortByParams) => void; |
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.
I think we should separate it from sortBy
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.
For compatibility reasons?
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.
I'm thinking maybe something like
onColumnSort?: ({ column, key, order }): Pick<SortByParams, 'key' | 'order'> & { column: Column & { [key: string]: unknown } }
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.
I mean { key: string; order: SortOrder; column: ColumnProps }
I noticed in one of my repo's that there are multiple |
types/index.d.ts
Outdated
|
||
type CallOrReturn<T, P = any[]> = T | (P extends any[] ? ((...p: P) => T) : ((p: P) => T)); | ||
|
||
export interface Column<T = unknown> { |
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.
How about ColumnConfig
for this interface to avoid clashing with <Column />
? @nihgwu WDYT?
It could be ColumnData
but I'm personally not a big fan of data in interfaces because of how this term behaves when we need plurals:
type MyConfig = {/* */}
myConfig: MyConfig = {}
myConfigs: MyConfig[] = []
type MyConfigs = MyConfig[]
myConfigs: MyConfigs = []
vs
type MyData = {/* */}
myData: MyData = {}
myDatas: MyData[] = [] // 😬
type MyDatas = MyData[] // 😬
myDatas: MyDatas = [] // 😬
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.
Sorry I'm a newbie for TS, what about just IColumn
or ColumnBase
here? Sorry I still don't understand we have both Coumn
and ColumnProps
types here
Besides that, we allow arbitrary data in the column definition to solve the closure problem, maybe we should add [key: string]: any
to the interface
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.
All of the component interfaces that have a column
or columns
prop (and there are quite a few) share the same type, which is Column
here. The <Column />
component also has same props but some additional as well. So by having Column
or IColumn
that interface can be re-used across all column
or columns
instances. And by extending Column
in ColumnProps
there is a single source of truth for what is a "column". Alternative being to duplicating it many many times which isn't ideal.
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.
column
and Column
should share exactly the same props, we will extract Column
's props to column
, Column
is actually just a sugar syntax
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.
Maybe ColumnBase
or BaseColumnProps
?
types/index.d.ts
Outdated
|
||
type CallOrReturn<T, P = any[]> = T | (P extends any[] ? ((...p: P) => T) : ((p: P) => T)); | ||
|
||
export interface Column<T = unknown> { |
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.
Sorry I'm a newbie for TS, what about just IColumn
or ColumnBase
here? Sorry I still don't understand we have both Coumn
and ColumnProps
types here
Besides that, we allow arbitrary data in the column definition to solve the closure problem, maybe we should add [key: string]: any
to the interface
types/index.d.ts
Outdated
* Custom column cell renderer | ||
* The renderer receives props `{ cellData, columns, column, columnIndex, rowData, rowIndex, container, isScrolling }` | ||
*/ | ||
cellRenderer?: CallOrReturn<React.ReactNode, { |
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.
for renderer we support element and elementType(function and class component), does this type support class component? like cellRenderer: ClassComponent
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.
hmm, i'm not sure but my inclination is that it does not. React.ReactNode
is very generic but i think it only covers the returned element types. So it can be ReactElement | ReactFragment | ReactPortal | string | number
etc... I'll double check though.
types/index.d.ts
Outdated
|
||
type CallOrReturn<T, P = any[]> = T | (P extends any[] ? ((...p: P) => T) : ((p: P) => T)); | ||
|
||
export interface Column<T = unknown> { |
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.
Can we just remove the T from Column
? that would make the types clearer, I don't think the rowData should be constrained with a certain type, the only restriction is the unique id
Please correct me is I'm wrong, I'm still learning 😄
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.
It's useful to have rowData
typed, see Ant'd <Select>
with a similar generic typing for value
. Works like a charm for restricting wrong options and ensuring the onChange callback has the right typing too 👍
Each table instance would be able to set its own type and thus all all relevant props will be type-safe. For example, you won't be able to assign a callback that has a different expectation about the data.
types/index.d.ts
Outdated
/** | ||
* The sort state for the table, will be ignored if `sortState` is set | ||
*/ | ||
sortBy?: SortByParams; |
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.
{ key: string; order: SortOrder }
types/index.d.ts
Outdated
* A callback function for the header cell click event | ||
* The handler is of the shape of `({ column, key, order }) => *` | ||
*/ | ||
onColumnSort?: ({ column, key, order }: SortByParams) => void; |
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.
I mean { key: string; order: SortOrder; column: ColumnProps }
types/index.d.ts
Outdated
} | ||
|
||
export interface TableComponents { | ||
TableCell?: CallOrReturn<React.ReactNode, { |
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.
they should be all elementType
types/index.d.ts
Outdated
onExpand: (expanded: boolean) => void | ||
} | ||
export const unflatten: any; | ||
export interface BaseColumnInfo { |
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.
what is this for?
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.
These are the types @kachkaev posted at the top of the thread that he said were used in your repo typings.
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.
I don't think those types should live in this repo
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.
Removed them
types/index.d.ts
Outdated
width: number | ||
} | ||
|
||
export interface FrozenColumnInfo extends BaseColumnInfo { |
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.
what is this for?
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.
from here: #193 (comment)
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.
If the only distinction between frozen and normal column infos is frozen?: true | "left" | "right"
could be worth having just one column info indeed 🤔
types/index.d.ts
Outdated
|
||
export interface FrozenColumnInfo extends BaseColumnInfo { | ||
frozen: true | ||
label: string |
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.
what's this?
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.
from here: #193 (comment)
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.
Hmm this could be our app-specific code got blended into the library type definitions. Thanks for spotting @nihgwu !
types/index.d.ts
Outdated
} | ||
|
||
export interface FrozenColumnInfo extends BaseColumnInfo { | ||
frozen: true |
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.
for frozen column it could be true | 'left' | 'right'
@jamesonhill @kachkaev Sorry for the late response, I'm pretty busy recently, I pushed my changes based on my local test demo, feedbacks are welcome |
types/index.d.ts
Outdated
*/ | ||
className?: string; | ||
hidden?: bool; |
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.
typo
any inputs here, we still need to add types for the utils, or we can address it in another PR |
@nihgwu Everything that we have so far looks good to me. From what I can see, we're missing types for |
@jamesonhill I don't know why I exported |
Gotcha, well then in that case i'll just focus on the utils. |
@jamesonhill I’m planning to release this with #213 , so I did some work on the typings for utils last night |
a lot of codes are copied from @sskiswani 's work in #93, great thanks |
types/index.d.ts
Outdated
|
||
export function normalizeColumns(elements: React.ReactNode[]): ColumnShape<any>[]; | ||
|
||
export function isObjectEqual(objA: any, objB: any, ignoreFunction?: boolean): boolean; |
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.
why not type objA
and objB
as object
?
let's move forward and hear feedbacks to improve the types |
@jamesonhill I got those error messages UPDATE: seems this commit could fix this issue 631d1bc |
01eae47
to
631d1bc
Compare
@nihgwu It's not wrong, TS just doesn't support union types for index signature types (at least last I checked). Using |
@@ -62,6 +63,7 @@ | |||
"@babel/plugin-transform-runtime": "^7.0.0", | |||
"@babel/preset-env": "^7.0.0", | |||
"@babel/preset-react": "^7.0.0", | |||
"@types/react": "^16.9.46", |
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.
This lib uses react 16.4. Are the typings for 16.9 consistent w/ 16.4?
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.
I think that should be OK as it's dev only to suppress the warning about the types from React
types/index.d.ts
Outdated
minWidth?: number; | ||
/** | ||
* Whether the column is frozen and what's the frozen side | ||
* Could be changed if we decide to allow Frozen.RIGHT |
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.
This comment somewhat confuses me. Frozen right is already supported, or am I misunderstanding?
Initial pass at adding type declarations for each component's props as well as typings used by various event handlers. Feel free to comment or modify.