typescript - 打字稿动态界面
问题描述
我有一个函数要转换为泛型 Typescript 以作为实用程序提供。我已经达到了它,但是当一个函数返回一个函数时会发生什么。我知道这不是必需的,但仍然
/**
* createConstants Type
*/
type createConstantsType =
<T extends string, U extends string>(namespace: T, prefix: U | null) =>
<V extends string>(...constants: V[]) => Record<V, string>;
/**
* function for creating namespaced constants
* @param {String} namespace the namespace for the constant to create
* @param {String} prefix the prefix for the constant to create
* @returns {Object} namespaced constants for a module/feature
*
* // Common approach
* export const NAMESPACE = 'manual';
* export const SIDEBAR_TOGGLE = `${NAMESPACE}/SIDEBAR_TOGGLE`;
* export const SIDEBAR_OPEN = `${NAMESPACE}/SIDEBAR_OPEN`;
* export const SIDEBAR_CLOSE = `${NAMESPACE}/SIDEBAR_CLOSE`;
*
* // Usage of this utility
* export const NAMESPACE = 'manual';
* export const SIDEBAR = createConstants(NAMESPACE, 'sidebar')('TOGGLE', 'OPEN', 'CLOSE');
*
* // which will generate:
* SIDEBAR = {
* TOGGLE: 'manual/SIDEBAR_TOGGLE',
* OPEN: 'manual/SIDEBAR_OPEN',
* CLOSE: 'manual/SIDEBAR_CLOSE',
* }
*
*/
export const createConstants: createConstantsType =
<T extends string, U extends string>(namespace: T, prefix: U | null = null) =>
<V extends string>(...constants: V[]): Record<V, string> => (
constants.reduce((result: Record<V, string>, constant: string): Record<V, string> => ({
[constant.toUpperCase()]:
`${namespace}/${(prefix) ? `${prefix.toUpperCase()}_` : ''}${constant.toUpperCase()}`,
...result,
}), {} as Record<V, string>)
);
解决方案
有几点需要注意:
String
当你的意思是 时不要使用string
。大写字母是对String
JavaScript 中全局对象的引用。- 避免将函数定义为
Function
. 的定义Function
非常广泛,即使你的函数使用了一些精确的类型和泛型,TypeScript 也会忽略所有这些,因为它被告知将其视为 anyFunction
。如果要创建函数类型,请以这种方式编写其签名:type MyFunction = (argument: number) => boolean
改为。 - 根据经验,如果您的参数是 type
string
,您可以从创建一个类型参数(泛型)并说出它开始extends string
。所以,<T extends string>(argument: T)
而不是(argument: string)
.
当您应用这些规则时,您的解决方案将如下所示:
export const createConstants = <T extends string, U extends string>(namespace: T, prefix: U | null = null) => <V extends string>(...constants: V[]): Record<V, string> => (
constants.reduce((result, constant) => ({
[constant.toUpperCase()]:
`${namespace}/${(prefix) ? `${prefix.toUpperCase()}_` : ''}${constant.toUpperCase()}`,
...result,
}), {} as Record<V, string>)
);
const test = createConstants('manual', 'SIDEBAR')('TOGGLE', 'OPEN', 'CLOSE')
请参阅TypeScript 游乐场。
推荐阅读
- javascript - Angular 中的 Chart.js 图表在调整浏览器窗口大小之前不会加载
- php - PHP 警告:在遍历数组时出现非法字符串偏移 ''
- node.js - 如何通过部署 Node.js AWS Beanstalk 解决 /tmp/.config 中的权限问题?
- html - 如何在网站加载时摆脱颜色闪烁
- asp.net-core - 如何为其他应用程序可以访问特定服务的应用程序实施适当的登录系统?
- java - 无法使用 spring-boot 应用程序从 Jaeger UI 跟踪服务
- html - 我如何将导航栏元素移动到左侧,除了导航栏的“帐户”元素,并将其放在右侧?
- python - Python:无法使用嵌套函数返回礼物
- javascript - 使用 javascript 将数据信息发布到 CGI 脚本
- r - 将一列字符转换为日期