typescript - 在 TypeScript 中的对象内查找类型
问题描述
我正在尝试在对象中引入查找类型。假设我的对象看起来像
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
我想在我的吸气剂中摆脱的东西。我试过代理吸气剂,但没有成功:
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
但是,如果你更喜欢保持它内联,你可以使用keyof PersonList['persons']
作为参数类型:
class PersonList {
persons = {
john: 'description of john',
bob: 'description of bob'
};
getPerson(name: keyof PersonList['persons']) {
return this.persons[name];
}
}
在您问过的评论中:
是否可以在抽象类中实现它?...在抽象类中实现getter会很棒,但到目前为止我还没有找到解决方案。
...带有指向此代码模板的链接:
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"'.
推荐阅读
- javascript - Javascript - 如何将单独的单个数组组合到单个数组?
- r - 查找lat-long coordiantes之间的距离需要很长时间R
- unix - 根据列的值更改文件中某些字段的值
- typo3 - TYPO3:如何使用flux:field.inline.fal 图像作为背景
- angular - 角排列的水果。将每个水果放在它自己的列表中
- javascript - 角度 8,无法读取未定义的属性“sortChange”
- .net-core - dotnet restore 依赖解析不拉最新版本
- javascript - ajax返回页面的html代码而不是响应
- flutter - 如何在flutter web中显示源代码?
- sql - 在 Flink SQL 中构建 JSON_Object 值