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.
type RowKey = string | number?
There was a problem hiding this comment.
isn't rowKey optional?
There was a problem hiding this comment.
I think @nihgwu is suggesting to create a new separate type and then use it here as
rowKey?: RowKeyThere was a problem hiding this comment.
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.
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.
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.
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.
yes, and more, like CallOrReturn<React.ReactNode> and CallOrReturn<React.ReactNode, Args>
There was a problem hiding this comment.
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.
I think we should separate it from sortBy
There was a problem hiding this comment.
For compatibility reasons?
There was a problem hiding this comment.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
{ 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.
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.
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.
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.
I don't think those types should live in this repo
types/index.d.ts
Outdated
| width: number | ||
| } | ||
|
|
||
| export interface FrozenColumnInfo extends BaseColumnInfo { |
There was a problem hiding this comment.
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.
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.
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
| * Whether the column is hidden | ||
| */ | ||
| className?: string; | ||
| hidden?: bool; |
|
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.
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 |
| "@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.
This lib uses react 16.4. Are the typings for 16.9 consistent w/ 16.4?
There was a problem hiding this comment.
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.
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.