![](/img/trans.png)
[英]Typescript: how to map array of types to distinct arguments via advanced types?
[英]How to map types of two arguments of function in Typescript?
如何实现这样的功能?
type SomeType = {
name: string;
quantity: number;
};
const someFunc = (
key: keyof SomeType /* what should be here? */,
value: SomeType[keyof SomeType] /* what should be here? */
) => {
// ...
};
someFunc("name", "John") // OK
someFunc("name", 10) // must be error
someFunc("quantity", "John") // must be error
someFunc("quantity", 10) // OK
我试过这个:
...
const someFunc = (
key: keyof SomeType
value: SomeType[keyof SomeType]
)
...
但这行不通,我明白为什么。 所以我不知道如何实现这个。
我认为没有 100% 万无一失的方法可以做到这一点。 您可以使用泛型类型参数关闭:
type SomeType = {
name: string;
quantity: number;
};
const someFunc = <Key extends keyof SomeType>(
key: Key,
value: SomeType[Key],
) => {
// ...
};
这样,您的示例就可以工作了:
someFunc("name", "John") // OK
someFunc("name", 10) // Error as desired
someFunc("quantity", "John") // Error as desired
someFunc("quantity", 10) // OK
但是,由于工会,它不是 100%。 我们可以为类型参数指定一个显式类型参数,然后强制它采用错误的key
和value
组合:
someFunc<"name" | "quantity">("name", 10) // wrong, but no error
这对函数内部的代码有影响,因为您希望缩小key
的类型以缩小value
的类型,但事实并非如此; 看到这个问题的答案。
对@TJ Crowder 解决方案的万无一失的改进并不是那么理想
它阻止您使用 union 但不检查值类型的正确性
type UnionToIntersection<U> =
(U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never
type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : true
type SomeType = {
name: string;
quantity: number;
age: number
};
const someFunc = <Key extends keyof SomeType>(
key: IsUnion<Key> extends true ? "No Union!" : Key,
value: SomeType[Key],
) => {
// ...
};
someFunc<"name" | "quantity">("name", 10) // error at argument 1, ideally should error at argument 2, but still an error regardless, a true negative case
someFunc<"quantity" | "age">("quantity", 10) // should not error, because both quantity and age are number, a false negative case
// still works as normal
someFunc("name", "John") // OK
someFunc("name", 10) // Error as desired
someFunc("quantity", "John") // Error as desired
someFunc("quantity", 10) // OK
如代码所示,不仅在错误的参数上出错,还有一个假阴性的情况
但这有关系吗? 不,它没有
因为无论如何都必须通过删除联合来修复错误,所以清除假阴性案例不会导致另一种类型的错误
所以最终结果是,它仍然会引导您找到正确的类型
这不是一个理想的方法,但它是有效的,它是安全总比错误好
一个问题是这对新手不友好,需要研究背景问题才能理解代码为什么这样写,为什么错误出现在错误的参数上或无缘无故出现。
对于那些新手来说,每次都会以失败告终,而我们都知道,他们接下来要做的就是怀疑自己存在的意义
你不可能像你给一个 5 岁的孩子解释的那样,所以 TS 应该承担责任
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.