簡體   English   中英

Typescript 泛型類型 - 類型“keyof T1”不能用於索引類型

[英]Typescript generic type - Type 'keyof T1' cannot be used to index type

我有驗證 forms 的功能,我希望 function 位於單獨的文件中,但我有一個類型問題, validationRequirements[fieldName]我收到錯誤Type 'keyof T1' cannot be used to index type '{ name: (value: string) => boolean; }'. Type 'keyof T1' cannot be used to index type '{ name: (value: string) => boolean; }'.

這是我的驗證要求:

const validationRequirements = {
    name: (value: string) => false, //mock
}

createValidationObj 的接口:

interface CreateValidationObjI<T1> {
    validation: T1
    fieldName: keyof T1
    value: string
}

在這里,我調用 function 來更新驗證 object,我將validationI I 作為 typescript 參數傳遞,然后我將其用作通用參數:

const onChangeValidation = ({ value, fieldName }: { value: string; fieldName: keyof typeof validation }) => {
    const validationObj = createValidationObj<validationI>({ validation, fieldName, value })
}

這是驗證 function,我希望 function 分開:

const createValidationObj = <T1 extends {}>({ validation, fieldName, value }: CreateValidationObjI<T1>) => ({
    ...validation,
    [fieldName]: {
        ...validation[fieldName],
        isValid: validationRequirements[fieldName](value), <-- Type 'keyof T1' cannot be used to index type '{ name: (value: string) => boolean; }'.
        isTouched: true,
    },
})

示例鏈接: 示例

問題

考慮這段代碼。 object 類型的Parent中的任何字段都可以分配給Child類型的 object(只要它們的類型匹配)。 這是因為Parent有鍵"a" | "b" "a" | "b" 因此,當然, parentObject具有childObject具有的鍵,但反之亦然,因為parentObject缺少來自childObject c

因此,簡而言之,我們分配的字段的 object 的鍵必須是我們分配的 object 的鍵的子集。

{}類型的鍵是一個空集,因此 function f3中的錯誤。

interface Parent {
    a: string
    b: string
}

interface Child {
    a: string
    b: string
    c: string
}

const parentObject: Parent = {
    a: "abc",
    b: "string"
}

const childObject: Child = {
    a: "abc",
    b: "string",
    c: "string"
}

type KeysOfParent = keyof Parent // "a" | "b"
type KeysOfChild = keyof Child // "a" | "b" | "c"

function f(field: keyof Parent) {
    childObject[field] = "abc" // OK
}

function f2(field: keyof Child) {
    parentObject[field] = "abc" // ERROR
}

function f3<T extends {}>(field: keyof T) {
    parentObject[field] = "abc" // ERROR
}

操場

因此,在問題中,在 function createValidationObj中, fieldName有鍵 - keyof {}這絕對不是validationRequirements鍵的子集(“名稱”)。 所以錯誤。

解決方案

如果它不違反您的要求,請完全刪除T1

interface validationI {
    name: {
        isValid: boolean
        isTouched: boolean
        errorMsg: string
    },
    field2: {
        isValid: boolean
        isTouched: boolean
        errorMsg: string
    },
}

const validation: validationI = {
    name: {
        isValid: false,
        isTouched: false,
        errorMsg: "Min 3 chars",
    },
    field2: {
        isValid: false,
        isTouched: false,
        errorMsg: "Min 3 chars",
    },
}
type X = keyof typeof validation

const validationRequirements = {
    name: (value: string) => false, //mock
    field2: (value: string) => false, //mock
}

interface CreateValidationObjI<T1 extends validationI> {
    validation: T1
    fieldName: keyof T1
    value: string
}

const createValidationObj = ({validation, fieldName, value}: CreateValidationObjI<validationI>) => ({
    ...validation,
    [fieldName]: {
        ...validation[fieldName],
        isValid: validationRequirements[fieldName](value),
        isTouched: true,
    }
})

const onChangeValidation = ({ value, fieldName }: { value: string; fieldName: keyof typeof validation }) => {
    const validationObj = createValidationObj({ validation, fieldName, value })
}

操場

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM