0

目前我有以下设置。

当我foo作为 Column.key 传递时,我希望 Column.formatter 的参数类型valuestring. 因为bar它应该是number

原样;Typescript 期望类型是所有可能的类型T。所以stringnumber

是否可以根据给定的键设置类型?

interface ColumnData {
    foo: string;
    bar: number;
};

type ColumnDataFormatter<T> = (value: T[keyof T]) => string;

class Column<T> {   
    constructor(
        public key: keyof T,
        public formatter: ColumnDataFormatter<T>
    ) {}
}
new Column<ColumnData>('foo', (value: string) => value);
new Column<ColumnData>('bar', (value: number) => value.toString());

-------------------------------------------------------------------
ERROR: TS2345
Types of parameters 'value' and 'value' are incompatible.    
Type 'string | number' is not assignable to type 'string'.
4

1 回答 1

0

不确定这是否是最简洁的解决方案,但您可以做几件事:

interface ColumnData {
    foo: string;
    bar: number;
};

type ColumnDataFormatter<T, K extends keyof T> = (value: T[K]) => string;

class Column<T, K extends keyof T> {   
    constructor(
        public key: K,
        public formatter: ColumnDataFormatter<T, K>
    ) {}
}

new Column<ColumnData, 'foo'>('foo', (value: string) => value);
new Column<ColumnData, 'bar'>('bar', (value: number) => value.toString());

或者

interface ColumnData {
    foo: string;
    bar: number;
};



type ColumnDataFormatter<T> = (value: T[keyof T]) => string;

class Column<T> {   
    constructor(
        public key: keyof T,
        public formatter: ColumnDataFormatter<T>
    ) {}
}
new Column<ColumnData>('foo', (value: string | number) => typeof value === 'string' ? value: value.toString());
new Column<ColumnData>('bar', (value: string | number) => typeof value === 'string' ? value: value.toString());

TS Playground 链接:https ://tsplay.dev/w8KGMW

于 2021-12-16T10:10:15.980 回答