![](/img/trans.png)
[英]Assign types to argument of generic mapping function in Typescript
[英]Typescript - type mapping fails inside a generic function
鉴于这些Typescript类型:
// Validation types
type Methods = 'firstName' | 'lastName' | 'email'
type Method<T> = {[K in keyof T]?: Methods }
type Row<T> = keyof T | Method<T>
type Mapping<T> = Array<Row<T>>
// Fields that will be accepted
type Fields = {
firstName: string
lastname: string
e?: string
}
这个数据:
// Data object, holding the form submission
const data: Fields = {
firstName: 'John',
lastname: 'Doe',
e: 'john@example.com'
}
// Map validation methods to the data fields
const mapping: Mapping<Fields> = [
'firstName',
'lastname',
{
e: 'email'
}
]
为什么这样做:
const validationFuncs: Method<Fields>[] = mapping.map(m => {
return typeof m === 'string' ? { [m]: m } : m;
})
// validationFuncs[0].firstName // works
但这不是吗?
function validate<T>(mapping: Mapping<T>) {
const validationFuncs: Method<T>[] = mapping.map(m => {
return typeof m === 'string' ? { [m]: m } : m;
})
}
Method<T>
的值必须是Methods
,它们只能是"firstName"
, "lastName"
或"email"
。 在您的通用示例中:
function validate<T>(mapping: Mapping<T>) {
const validationFuncs: Method<T>[] = mapping.map(m => {
return typeof m === 'string' ? { [m]: m } : m;
})
}
类型T
可以是任何东西......例如, {nope: string}
。 在这种情况下, keyof T
是"nope"
keyof T
"nope"
,并且声明的validationFuncs
类型是{nope?: Methods}[]
。
但是如果mapping
是["nope"]
(有效的Mapping<{nope: string}>
),那么validationFuncs
在运行时将是[{nope: "nope"}]
。 但那不是{nope?: Methods}[]
,因为validationFuncs[0].nope
是"nope"
validationFuncs[0].nope
"nope"
而不是undefined
或者Methods
的三个允许值中的任何一个。 所以编译器会警告你。 这一切都对我有意义。
在您的非通用“工作”示例中:
const validationFuncs: Method<Fields>[] = mapping.map(m => {
return typeof m === 'string' ? { [m]: m } : m;
})
一些奇怪的事情正在发生。 Method<Fields>
相当于
type MethodFields = {
firstName?: Methods
lastname?: Methods
e?: Methods
}
但是的类型检查{ [m]: m }
无法正常工作,因为与计算出的密钥的打字稿错误的 ,这可能是固定在打字稿2.6; 不确定。
编译器应该(但没有)意识到{ [m]: m }
只能保证{firstName:"firstName"}
, {lastname:"lastname"}
或{e:"e"}
,最后两个它们都是无效的Method<Fields>
元件(请注意在小写“n”的lastname
)。 相反,类型检查器将{ [m]: m }
的类型扩展为类似{ [k: string]: keyof Fields }
,这显然足够宽以匹配Method<Fields>
,而不是我理解的方式。 无论如何,它不应该进行类型检查; 这是TypeScript中的错误或设计限制。
在这两种情况下,您都没有以符合您声明的类型的方式实现代码。 我不知道你的类型是否正确,但实现是错误的,反之亦然,或其他什么。 我希望你现在有足够的信息来取得进展。 祝好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.