gpt4 book ai didi

typescript - 在 TypeScript 中的对象内查找类型

转载 作者:行者123 更新时间:2023-12-05 02:11:42 24 4
gpt4 key购买 nike

我正在尝试在对象中引入查找类型。假设我的对象看起来像

class PersonList {
persons = {
john: 'description of john',
bob: 'description of bob'
}
}

我想要一个 getter 从 persons 中获取一个人,但没有指定 persons 对象。

文档中的getProperty

function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key]; // Inferred type is T[K]
}

想要一个 obj,我想在我的 getter 中去掉它。我试过代理 setter/getter ,但没有成功:

class PersonList {
persons = {
john: 'description of john',
bob: 'description of bob'
};

getPerson(name) {
return this.getProperty(this.persons, name);
}

private getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key]; // Inferred type is T[K]
}
}

遗憾的是,当尝试执行诸如 personList.getPerson('someonenotincluded'); 之类的操作时,这不会引发错误 - 此外,自动完成功能也不起作用。

最佳答案

我会采用该内联类型并为其命名(但请继续阅读,您不必):

interface Persons {
john: string;
bob: string;
}

然后你可以使用keyof Persons作为getPerson中的参数类型:

class PersonList {
persons: Persons = {
john: 'description of john',
bob: 'description of bob'
};

getPerson(name: keyof Persons) {
return this.persons[name];
}
}

那么如果 pl 是一个 PersonList:

console.log(pl.getPerson('john')); // Works
console.log(pl.getPerson('someonenotincluded')); // Error

Live on the playground .

但是,如果您希望保持内联,您可以使用 keyof PersonList['persons'] 作为参数类型:

class PersonList {
persons = {
john: 'description of john',
bob: 'description of bob'
};

getPerson(name: keyof PersonList['persons']) {
return this.persons[name];
}
}

Live on the playground .


在您提出的评论中:

is it possible to implement this in an abstract class? ... it would be awesome to implement the getter in the abstract class, but I haven't found a solution so far.

...带有此代码模板的链接:

abstract class AbstractPersonList {
protected abstract persons: { [name: string]: string };
}

class Persons extends AbstractPersonList {
persons = {
john: 'this is john',
}
}

class MorePersons extends AbstractPersonList {
persons = {
bob: 'this is bob',
}
}

您可以参数化AbstractPersonList:

abstract class AbstractPersonList<T extends {[name: string]: string}> {
// ------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
protected abstract persons: T;
public getPerson(name: keyof T): string {
return this.persons[name];
}
}

然后你会:

class Persons extends AbstractPersonList<{john: string}> {
// -------------------------------------^^^^^^^^^^^^^^^^
persons = {
john: 'this is john',
}
}

class MorePersons extends AbstractPersonList<{bob: string}> {
// -----------------------------------------^^^^^^^^^^^^^^^
persons = {
bob: 'this is bob',
}
}

这导致了这些结果,我认为这就是您正在寻找的:

let n = Math.random() < 0.5 ? 'john' : 'bob';

const p = new Persons();
console.log(p.getPerson('john')); // Works
console.log(p.getPerson('bob')); // FAILS: Argument of type '"bob"' is not assignable to parameter of type '"john"'.
console.log(p.getPerson(n)); // FAILS: Argument of type 'string' is not assignable to parameter of type '"john"'.

const mp = new MorePersons();
console.log(mp.getPerson('john')); // FAILS: Argument of type '"john"' is not assignable to parameter of type '"bob"'.
console.log(mp.getPerson('bob')); // Works
console.log(mp.getPerson(n)); // FAILS: Argument of type 'string' is not assignable to parameter of type '"bob"'.

Live on the playground .

关于typescript - 在 TypeScript 中的对象内查找类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57078576/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com