Typescript KeyOf - 数组或对象 - 绝望
Posted
技术标签:
【中文标题】Typescript KeyOf - 数组或对象 - 绝望【英文标题】:Typescript KeyOf - Array or Object - Desperate 【发布时间】:2018-11-09 23:29:00 【问题描述】:我有以下课程.....
export class Person<T, C = T>
lens: any = null;
private value: T;
constructor(value: T, newLens?: any)
this.value = value;
this.lens = newLens;
at<K extends keyof C>(path: keyof C): Person<T, C[K]>
if(!this.lens)
return new Person<T, C[K]>(this.value, Lens.lens(path));
return new Person<T, C[K]>(this.value, Lens.compose(this.lens)(Lens.lens(path)));
get(): any
if(!this.lens) return this.value;
return Lens.get(this.lens)(this.value);
set(f: (newValue: any) => any): T
return Lens.set(this.lens)(f(this.get()))(this.value);
我的问题是,当我尝试在一个对象上使用我的新 Person 类时,我得到了不正确的行为.....
const TestPerson =
name:
name: "steve"
,
siblings: [name: "shanon"]
age: Infinity
const test = new Person(TestPerson).at("name").at("name") // works....
const test2 = new Person(TestPerson).at("siblings").at(0) // fails
const test3 = new Person(TestPerson).at(siblings").at("0") // still fails.
const test4 = new Person(TestPerson).at("nonexistantproperty") //correctly fails.
我的问题是我需要一个可以处理 keyof 对象和 keyof 数组的“AT”函数,但似乎无论我如何重做它都无法实现。
在我看来,这似乎是 typescript 的一个巨大缺陷,数组和对象都只是底层的对象,因此对象类型上的 keyof 和数组类型上的 keyof 应该以相同的方式工作。
【问题讨论】:
【参考方案1】:最简单的解决方案是等到 typescript 2.9(在撰写本文时在RC,应该很快就会发布)。在 2.9 之前 keyof
只返回字符串索引,在 2.9 中这将包括数字和符号键。请参阅PR。在 2.9 中,您的代码将按预期工作而无需任何更改。
在 2.8 中你可以使用条件类型来达到类似的效果
type CReturn<C, K extends keyof C> = C extends Array<any> ? C[number] : C[K];
export class Person<T, C = T>
lens: any = null;
private value: T;
constructor(value: T, newLens?: any)
this.value = value;
this.lens = newLens;
at<K extends keyof C>(path: C extends Array<any> ? number : K): Person<T, CReturn<C, K>>
if(!this.lens)
return new Person<T, CReturn<C, K>>(this.value, Lens.lens(path));
return new Person<T, CReturn<C, K>>(this.value, Lens.compose(this.lens)(Lens.lens(path)));
const TestPerson =
name:
name: "steve"
,
siblings: [ name: "shanon" ],
age: Infinity
const test = new Person(TestPerson).at("name").at("name") // works....
const test2 = new Person(TestPerson).at("siblings").at(0) // ok
const test21 = new Person(TestPerson).at("siblings").at(0).at("name") //ok
const test4 = new Person(TestPerson).at("nonexistantproperty") //correctly fails.
【讨论】:
现在正在运行测试用例,但看起来这很有效,实际上花了 4-5 小时试图输入这个,非常感谢。如果我的一个测试用例很快失败,我可能会发表评论 你就是那个男人,非常感谢你编译的所有内容,因为从 styled-component.d.ts 从交换到 2.9 时出现了一些 Omit 和 Diff 错误以上是关于Typescript KeyOf - 数组或对象 - 绝望的主要内容,如果未能解决你的问题,请参考以下文章
[TypeScript] type、typeof、keyof
Typescript 'keyof' 关键字在使用 react setState 函数时出错
[TypeScript] Query Properties with keyof and Lookup Types in TypeScript
TypeScript 中的“keyof typeof”是啥意思?