Я работаю над функцией, которая принимает два параметра типа, T и K. T расширяет тип Record, а K является ключом первого типа. Есть ли способ ограничить тип ключа на основе его типа поиска (T[K]) в T?
У меня есть следующие типы:
type FormValue = string | number | boolean | null;
type FormValues = Record<string, FormValue>;
и следующая функция:
function numericFormHelperFunc<T extends FormValues, K extends keyof T>(key: K, formValues: T) {}
Есть ли способ ограничить, какие клавиши можно использовать для этой функции, чтобы были разрешены только клавиши в formValues, которые имеют типы поиска, скажем, number? В основном способ утверждать, что T[K] extends number.
Например, если у меня есть этот пример типа формы:
type MyFormValues = {
name: string;
age: number;
numPets: number;
}
Могу ли я добавить ограничение типа к numericFormHelperFunc, чтобы можно было использовать только ключи "age" и "numPets"?
Я ищу статический способ сделать это, чтобы получать предупреждения редактора о попытке использовать numericFormHelperFunc("name", myFormValues). Также хотелось бы, чтобы машинописный текст знал, что значение при поиске key в formValues имеет определенный тип, а не просто T[K] (например, чтобы числовые методы и операторы можно было использовать без утверждений типа).






Вот решение:
type FormValue = string | number | boolean | null;
type FormValues = Record<string, FormValue>;
type MyFormValues = {
name: string;
age: number;
numPets: number;
}
/**
* Takes two arguments,
* T - indexed type
* Allowed - allowed types
*
* Iterates through all properties and check
* if property extends allowed value
*/
type Filter<T, Allowed> = {
[P in keyof T]: T[P] extends Allowed ? P : never
}[keyof T]
function numericFormHelperFunc<T extends FormValues>(key: Filter<MyFormValues, number>, formValues: T) { }
numericFormHelperFunc('age', {'sdf':'sdf'}) // ok
numericFormHelperFunc('numPets', {'sdf':'sdf'}) // ok
numericFormHelperFunc('hello', {'sdf':'sdf'}) // error
numericFormHelperFunc('2', {'sdf':'sdf'}) // error
numericFormHelperFunc('name', {'sdf':'sdf'}) // error
Для понимания, причина, по которой это работает, заключается в том, что AnyType | never === AnyType.
Это плюс строка [keyof T] в конце, да.
Определенно касается основного вопроса моего вопроса, спасибо. Для этого может потребоваться открыть отдельный вопрос, но есть ли способ сообщить редактору о базовом типе при использовании типа поиска? В этом случае было бы неплохо иметь возможность обрабатывать значение для данного ключа как number без необходимости делать какие-либо утверждения типа. Это возможно?
Кажется, это возможно, если использовать фактический тип FormValues, но не с T extends FormValues (по крайней мере, без дополнительной обработки).
Не уверен, что это возможно
Это нормально для вас typescriptlang.org/play?ts=3.9.7#code/… ?