【问题标题】:Is it possible to infer the type of a generic index signature?是否可以推断出通用索引签名的类型?
【发布时间】:2019-08-29 18:23:17
【问题描述】:

我不想创建用于验证对象的通用函数。 我希望它接受以下签名的选项对象:

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] 
    ])
}

【问题讨论】:

    标签: typescript


    【解决方案1】:

    我强烈建议放弃使用Map,如果其目的只是为了保存基于字符串的键的值。这就是一个普通的旧对象的用途。对 TypeScript 来说重要的是,有很多基于对象的类型支持,您可以通过 mapped type 轻松地表示您对 validators 的期望行为,如下所示:

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

    如果由于某种原因您需要继续使用Map,则内置的TypeScript typings 将不起作用,因为它们更像是一个记录类型,其中每个键都是K,每个值都是V并且这两种类型是独立的。可以表示一种称为ObjectMap 的新类型,其类型基于键和值之间的潜在关系,但这是为了获得你要去的地方而进行的大量类型转换。

    希望有所帮助;祝你好运!

    【讨论】:

    • 谢谢你,这很好用!我从基于对象的方法开始,但在使用 keyof T 作为索引签名时遇到了一些问题,但似乎我需要阅读映射类型。再次,非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-24
    • 2017-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多