reactjs - 基于函数参数的条件类型检查
问题描述
我正在编写一个自定义 Hook,它可以采用一个或两个字符串,或者一个具有更细粒度参数的对象。我想添加一个条件类型检查来检查该参数的类型并基于它做一些逻辑。以下是相关的片段:
// The hook itself
const [error, loading, data] = useFirestore('posts', 'test'); // in a string version
const [error, loading, data] = useFirestore({...someProps}); // in a object version version
// The types that i defined for them
type queryType<T> = T extends string ? string : documentQueryType;
type docType<T> = T extends string ? string : never;
type documentQueryType = {
collection: string;
query: string[] | string[][];
limit: number;
orderBy: string; // todo limit this to be only special words
order: string; // todo same as above
startAt: number;
endAt: number;
};
// The function that is in the question
export const useFirestore = <T>(query: queryType<T>, doc?: docType<T>) => {...rest of the function
我将如何使最后一个片段工作,以便在传递一个对象时它设置doc
为从不,而当传递一个字符串时将其设置doc
为字符串?
解决方案
这可以通过条件类型部分实现,但它可能不是 100% 类型安全的。由于是可选的,因此当是 adoc
时不需要它,并且仍然允许当是对象时。query
string
undefined
query
但是,如果这两种情况都不是问题,则可以使用条件类型来实现:
// Simplified type
type DocumentQueryType = {
collection: string;
};
// The two types of queries that are accepted
type QueryTypes = string | DocumentQueryType;
// Given the query type, infer the doc type
type InferDocType<QueryType> = QueryType extends string ? string : never;
const useFirestore = <QueryType extends QueryTypes>(query: QueryType, doc?: InferDocType<QueryType>) => { }
// Valid Examples
useFirestore('posts', 'test');
useFirestore({ collection: "" });
// Valid Examples (may not want these?)
useFirestore('posts');
useFirestore({ collection: "" }, undefined);
// Invalid Examples
useFirestore({ collection: "" }, "test");
// Argument of type '"test"' is not assignable to parameter of type 'undefined'.(2345)
useFirestore('posts', null);
// Argument of type 'null' is not assignable to parameter of type 'string | undefined'.(2345)
推荐阅读
- html - 剪辑路径的替代方法:Internet Explorer 8 中的 inset()
- javascript - 如何在不使用数据库的情况下在html页面中单击提交按钮时显示表单数据
- powershell - Powershell - 将文件移动1个文件夹更深
- python - 计算列表列表的平均值
- amazon-web-services - AWS 队列在响应中不返回 MessageAttributeNames
- ruby-on-rails - Rails 4 范围连接以查找非此即彼的关系
- aspnetboilerplate - 如何在 ASP.NET 样板中更改侧边栏菜单项的图标?
- eclipse - 流程建模和流程开发透视图在 Eclipse 中不可见
- java - Maven 编译错误 try-with-resources
- java - 有条件地在 jooq 准备语句中包含子句