【发布时间】:2018-09-08 02:35:46
【问题描述】:
我正在尝试在 typescript 2.8 中探索新的 conditional types。
例如,我有一些具有数组属性的对象,这些对象在我的流程中必须只有一个元素,我想获得这个值。 这是code I thought should work,它正确地只允许传入相关的属性,但我不知道如何指定返回类型。我收到以下编译错误:
类型
number不能用于索引类型Pick<T, { [K in keyof T]: T[K] extends any[] ? K : never; }[keyof T]>[K]。
并且n 和s 的n 和s 的类型被推断为number|string 而不是number 和string。
代码如下:
type ArrayProperties<T> = Pick<T, {
[K in keyof T]: T[K] extends Array<any>? K : never
}[keyof T]>;
const obj = {
a: 4,
n: [2],
s: ["plonk"]
};
// Compilation error on next line
function single<T, K extends keyof ArrayProperties<T>>(t: T, k: K): ArrayProperties<T>[K][number] {
const val = t[k];
if (!Array.isArray(val))
throw new Error(`Expected ${k} to be an array`);
if (val.length !== 1)
throw new Error(`Expected exactly one ${k}`);
return val[0];
}
const n = single(obj, "n"); // 'n' should be of type 'number'
const s = single(obj, "s"); // 's' should be of type 'string'
const a = single(obj, "a"); // Should fail to compile (OK)
【问题讨论】:
-
你不能使用
ArrayProperties<T>[K][number]作为返回类型,因为打字稿没有检查数组属性中元素的数据类型,例如。s: ["plonk"]这里的返回类型是string而不是数字 -
关于 n,s 的类型,它作为联合类型返回,而不是单个类型。您可以使用
ArrayProperties<T>[K][any]或简单地使用ArrayProperties<T>[K]它应该编译 -
@Niladri 我认为打字稿应该推断出每个
K的类型,因此如果用"n"调用,那么ArrayProperties<T>["n"]应该是一个数字数组,ArrayProperty<T>["n"][number]应该是number跨度>
标签: typescript generics typescript2.8 conditional-types