typescript - 打字稿打字可以确保函数返回请求的键吗?
问题描述
一些 Web 服务根据请求的属性提供内容。我想创建一个函数来获取属性,在内部调用 Web 服务并返回请求的数据。
使用数据的函数现在应该知道特定键现在不是未定义的。
在自己寻找解决方案时,我发现了一些可能有帮助的东西,但我无法从中创造出有用的东西:
还有一些额外的麻烦:在这种情况下,总是有一些默认属性,比如 id 。
interface Something {
id: string;
foo?: string;
bar?: number;
}
// use 'keyof Something' in some ways here?
type OptionalProp = 'foo' | 'bar'
type SomethingSpecific<K extends keyof Something> = {
[k in K]: NonNullable<Something[k]>
};
function get(properties: OptionalProp[]): Something {
const result: Something = {
id: '1337'
};
if (properties.includes('foo')) {
result.foo = 'bar';
}
if (properties.includes('bar')) {
result.bar = 42;
}
return result;
}
console.log(usage());
function usage(): number {
const result = get(['bar']);
return result.bar * 1;
}
解决方案
因此,有一种方法可以确定类型的哪些键是可选的,您还可以为该函数提供调用签名,该get()
函数承诺返回 aSomething
以及现在需要的一些以前可选的属性(最好是它是一个重载的函数,以便实现签名可以像以前一样保持松散;否则你会在实现中收到很多抱怨)。另请注意,Required<T>
在标准库中调用了一个类型别名,它采用对象类型T
并返回一个新类型,现在需要所有可选属性。使用Required<T>
andPick<T, K>
和的组合应该可以工作:
interface Something {
id: string;
foo?: string;
bar?: number;
}
// get the optional keys of an object type
type OptionalKeys<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? K : never }[keyof T];
type OptionalProp = OptionalKeys<Something>
// make get() a generic function that returns an intersection of Something with
// a Required<Pick<Something, K>> for the passed-in K parameters
function get<K extends OptionalProp>(
properties: K[]
): Required<Pick<Something, K>> & Something;
function get(properties: OptionalProp[]): Something {
// impl here
return null!
}
const result = get(['bar']);
// const result: Required<Pick<Something, "bar">> & Something
result.bar * 1; // okay now
这应该适合你。请注意,返回的类型get()
将是一个交集类型,如Required<Pick<Something, "bar">> & Something
. 如果你想要一个更直接的属性包对象类型,你可以将get()
签名更改为对实现者来说更丑陋但对调用者来说更好的东西:
function get<K extends OptionalProp,
R extends Something=Required<Pick<Something, K>> & Something
>(properties: K[]): { [P in keyof R]: R[P] };
function get(properties: OptionalProp[]): Something { /* impl */ }
// impl here
return null!
}
const result = get(['bar']);
//const result: {
// bar: number;
// id: string;
// foo?: string | undefined;
//}
好的,希望有帮助。祝你好运!
推荐阅读
- apache-kafka - 通过在 Kafka Spout 中使用新的 Kafka 版本 2.1.0 和 Apache Storm 1.2.2 来获取 ClassNotFoundException
- tensorflow - 无法连接到 X 服务器 GOOGLE COLAB
- ios - Gmail 有没有办法从 UIapplication.shared.open url 的文本中识别换行符
- mysql - mysql如何从偶数行中找到中位数
- reactjs - 如何使用 ReactJS 打开多个消息框
- r - 如何取消嵌套在 data.frame 列中的列表?
- javascript - 如何在具有嵌套对象的第三方库上创建间谍 - Excel.Workbook.xlsx.WriteFile()
- swagger-ui - 在 Swagger UI 中使用相同架构的多个错误代码
- c++ - 从哪里获得 _fileno 和 _O_U16TEXT?
- reactjs - React Hooks setTimeout 和 clearTimeout