我有验证表单的函数,我希望该函数位于一个单独的文件中,但我有 validationRequirements[fieldName]
的类型问题,我收到错误 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
}
这里我调用一个函数来更新验证对象,我将 validationI
作为打字稿参数传递,然后我将它用作通用:
const onChangeValidation = ({ value, fieldName }: { value: string; fieldName: keyof typeof validation }) => {
const validationObj = createValidationObj<validationI>({ validation, fieldName, value })
}
这是验证函数,我想单独使用该函数:
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,
},
})
链接到示例:Example
答案 0 :(得分:1)
考虑这个代码。 Parent
类型的对象中的任何字段都可以分配给 Child
类型的对象(只要它们的类型匹配)。这是因为 Parent
有键 "a" | "b"
。因此,当然,parentObject
具有 childObject
具有的键,但反之亦然,因为 parentObject
缺少 c
中的键 childObject
。
所以,简而言之,我们要为其分配字段的对象的键必须是我们要分配给的对象的键的子集。
{}
类型的键是空集,因此函数 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
}
因此,在问题中,在函数 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 })
}