I'm trying to build a table interface that provides strict typing on the value a table column has and a function that executes on the column value and returns a string. I'm having issues using generics in my function parameter however. Below is a simple example of what I'm doing. I'm using Typescript 3.9.5
/**
* Interface for of a single column
*/
interface ColumnInfo<T, K extends keyof T> {
column: K,
cellFactory: (value: T[K]) => string
}
/**
* Interface for all table columns. Only single row for debugging purposes.
*/
interface Columns<T> {
columns: ColumnInfo<T, keyof T>;
};
/**
* Row implementation
*/
type RowImpl = {
id: string;
c1: string; //Could be number, Date, etc, simplified for now
c2: string;
}
/**
* id column implementation
*/
const columnInfo: ColumnInfo<RowImpl, 'id'> = {
column: 'id',
cellFactory: () => ''
}
/**
* Table columns Implementation. Currently only accepting a single column for debugging
*/
const columns: Columns<RowImpl> = {
columns: columnInfo
}
I'm currently getting an error on the columns object stating...
Type 'ColumnInfo<RowImpl, "id">' is not assignable to type 'ColumnInfo<RowImpl, "id" | "c1" | "c2">'. Type '"id" | "c1" | "c2"' is not assignable to type '"id"'. Type '"c1"' is not assignable to type '"id"'.ts(2322)
I'm not sure why it's trying to assign the union to the specific type as I'm using T[K]. I simplified the cellFactory object to just be T[K] to narrow down the issue, however it works now.
interface ColumnInfo<T, K extends keyof T> {
column: K,
cellFactory: T[K]
}
/**
* Interface for all table columns. Only single row for debugging purposes
*/
interface Columns<T> {
columns: ColumnInfo<T, keyof T>;
};
/**
* Row implementation
*/
type RowImpl = {
id: string;
c1: number;
c2: string;
}
/**
* id column implementation
*/
const columnInfo: ColumnInfo<RowImpl, 'id'> = {
column: 'id',
cellFactory: ''
}
/**
* Table columns Implementation. Currently only accepting a single column
*/
const columns: Columns<RowImpl> = {
columns: columnInfo
}
With cellFactory as T[K] instead of (val: T[K]) => string it works. Why is this? I'd assume if it can infer the T[K] both examples should work but the function parameter isn't. Can someone explain what my issue is and what I need to change to get a working interface?
Thanks
cellFactory: keyof typeof Tshould work for you, since K shouldn't extend from keyof in the first place (in this use case). - DivisionByZero