LINUX.ORG.RU

TypeScript: принимать только список объектов в каждом из которых есть property типа number

 


0

1
type NumericPropsOf<T> = {
    [K in keyof T]: T[K] extends number ? K : never;
}[keyof T];

function findRow<T extends Record<string, any>>(
    table: T[], value: number, field: NumericPropsOf<T>
): T | undefined {
    for (let i = 0; i < table.length; i++) {
        if (Math.abs(table[i][field] - value) < 0.01) return table[i];
    }
}

findRow(
    [
        { a: 1, b: 'first' },
        { a: 2, b: 'second' },
        { a: 't3', b: 'third' },
    ],
    2.005,
    'a'
); // Сделать так что бы выдавалась ошибка т.к. последний объект в списке имеет prop 'a' не number.

Возможно ли?

Тебе нужно использовать юнион с типом-параметром и { [field]: number }:

const findRow = <F extends string, T extends Record<string, any>>(
    table: (T & Record<F, number>)[], /* T здесь -- всё остальное кроме field */
    value: number,
    field: F
) => table.find(row => Math.abs(row[field] - value) < 0.01); /* за использование for в таком простом примере тебя закопают на любом ревью, укажи явно, что ты хочешь сделать */

findRow(
    [
        { a: 1, b: 'first' },
        { a: 2, b: 'second' },
        { a: 't3', b: 'third' }, /* => Type 'string' is not assignable to type 'number'.(2322) */
    ],
    2.005,
    'a'
);

А возвращаемый тип выведется сам.

Princesska ★★★ ()
Последнее исправление: Princesska (всего исправлений: 1)
Ответ на: комментарий от Princesska

Отлично!

Там логика сложнее чем в примере, сократил для краткости, но суть в том что если позволить строковые значения возможны бессмыссленные результаты на выходе из-за неявной конвертации в NaN.

marvelwebtech13 ()