Можно ли вывести тип общей подписи индекса?

Я не хочу создавать общую функцию для проверки объектов. Я хочу, чтобы он принимал объект параметров со следующей подписью:

export interface ValidationOptions<T, K extends keyof T = keyof T> {
  validators: Map<K, (value: T[K]) => string | null>    
}

Я хочу иметь возможность сопоставить K с массивом функций проверки, которые принимают аргумент типа T[K]. У меня проблема в том, что T[K] будет разрешать каждое возможное значение в T, а не конкретное значение для данного ключа.

Код ниже должен, надеюсь, пояснить, что я имею в виду.

export interface ValidationOptions<T, K extends keyof T = keyof T> {
    validators: Map<K, (value: T[K]) => string | null>    
}

function fooValidator(value: string) {
    if (value === "foo") {
        return "Value can't be foo"
    }

    return null;
}

function isNotTrueValidator(value: boolean) {
    if (!value) {
        return "Value must be true"
    }

    return null;
}

interface ObjectToValidate {
    stringy: string;
    booly: boolean;
}


//(value: T[K]) => string | null will resolve to value: string | boolean here
//Can i make it resolve to the type for the given property instead? 
const options: ValidationOptions<ObjectToValidate> = {
    //This results in an error with strictFunctionTypes enabled
    validators: new Map([
        //How can i 
        ["stringy", fooValidator] 
    ])
}
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Мне нравится библиотека Mantine Component , но заставить ее работать без проблем с Remix бывает непросто.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
TypeScript против JavaScript
TypeScript против JavaScript
TypeScript vs JavaScript - в чем различия и какой из них выбрать?
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Не все нужно хранить на стороне сервера. Иногда все, что вам нужно, это постоянное хранилище на стороне клиента для хранения уникальных для клиента...
Что такое ленивая загрузка в Angular и как ее применять
Что такое ленивая загрузка в Angular и как ее применять
Ленивая загрузка - это техника, используемая в Angular для повышения производительности приложения путем загрузки модулей только тогда, когда они...
0
0
588
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я настоятельно рекомендую отказаться от использования Map, если целью является просто хранение значений для строковых ключей. Вот для чего нужен старый добрый объект. Что важно для TypeScript, существует большая поддержка объектных типов, и вы можете легко представить поведение, которое вы ожидаете от validators, с помощью отображаемый тип, например:

export interface ValidationOptions<T> {
    validators: { [K in keyof T]?: (value: T[K]) => string | null }
}

const options: ValidationOptions<ObjectToValidate> = {
    validators: {
        stringy: fooValidator
    }
}

Если по какой-то причине вам нужно продолжать использовать Map, встроенный Типы TypeScript не будет работать, потому что они больше похожи на тип записи, где каждый ключ — K, а каждое значение — V, и эти два типа независимы. Можно представить новый тип с именем, скажем, ObjectMap, типизация которого основана на лежащей в основе взаимосвязи между ключами и значениями, но это слишком много подтасовок типов, чтобы понять, куда вы идете.

Надеюсь, это поможет; удачи!

Спасибо, это работает отлично! Я начал с объектно-ориентированного подхода, но столкнулся с некоторыми проблемами с использованием keyof T в качестве подписи индекса, но, похоже, мне нужно прочитать сопоставленные типы. Еще раз большое спасибо!

Erik Johansson 08.04.2019 17:47

Другие вопросы по теме