typescript - 函数参数中的映射类型
问题描述
我在文件中有一个屏幕列表:
文件1.ts
export const LANDING = 'landing.Landing'
export const REGISTER = 'landing.Register'
export const LOGIN = 'landing.Login'
以及另一个文件中每个屏幕的道具列表
文件2.ts
type LandingProps = { foo: string }
type RegisterProps = { bar: number }
type LoginProps = { baz: object }
我想navigate
在另一个文件中创建一个函数,例如:
文件3.ts
import { LANDING, REGISTER, LOGIN } from 'file1'
import { LandingProps, RegisterProps, LoginProps } from 'file2'
const screens = [LANDING, REGISTER, LOGIN] as const
type ScreenType = typeof screens[number]
type Props = LandingProps | RegisterProps | LoginProps
function navigate(screen: ScreenType, props: Props) {
console.log('Navigation to screen ', screen)
console.log('Props are: ', props)
}
如何键入参数props
以使道具与相应的 ScreenType 匹配?
顺便说一句,是否可以根据file1的所有导出创建一个类型,而不必指定哪个?
解决方案
为了让编译器props
根据 的类型来限制 的类型screen
,你需要给它一个映射。在您的情况下,最简单的方法是制作一个虚拟接口,因为类型props
已经类似于键:
interface ScreenPropsMapping {
[LANDING]: LandingProps,
[REGISTER]: RegisterProps,
[LOGIN]: LoginProps
}
因为LANDING
etc 是const
字符串文字,我们可以将它们用作接口中的计算键。
然后你给出navigate()
一个这样的通用签名:
function navigate<K extends keyof ScreenPropsMapping>(
screen: K, props: ScreenPropsMapping[K]
) {
}
在这里,K
被限制为映射接口的键之一,并且props
被限制为该键处的特定属性类型:
navigate(LANDING, { foo: "" }); // okay
navigate(LANDING, { bar: 1 }); // error
至于您的旁注,如果您真的希望一个类型成为模块中所有导出值类型的联合,您可以执行以下操作:
import * as File1 from 'file1'
type File1Types = typeof File1[keyof typeof File1];
// type File1Types = "landing.Landing" | "landing.Register" | "landing.Login"
好的,希望有帮助;祝你好运!
推荐阅读
- arrays - 用于填充工作表上的多个列的数组
- push-notification - 如何使用 FCM 仅向使用主题的离线设备发送推送通知?
- javascript - 卖家和城市的 v-model 表单字段为空
- c# - MS Test 单元测试框架不会命中它的构造函数
- python-3.x - 如何使用 matplotlib python 绘制百分比值
- apache-superset - Apache Superset 永久删除表名
- greenplum - 绿梅 | 备份 | 错误=>错误消息:5:写入错误(SQLSTATE 22P04)
- android - 中间有中断的滑块(离散)用于本机反应
- php - 用户登录后 Wordpress 内存超出
- javascript - 有什么方法可以在 ionic 中验证应用程序签名?