reactjs - 具有多种类型的打字稿,如何确定哪种类型具有某些道具
问题描述
假设我有 3 种类型。A型、B型和C型
typeA 有一个 name 属性,而 typeB 和 typeC 没有
当我用类似的代码渲染它时;
interface propTypes {
post: typeA | typeB | typeC
}
..... some react code ....
return(
{post?.name && component})
但它返回错误:“类型 'typeA| typeB | typeC 上不存在属性 'name'
我试过 post instanceof typeA 但它返回一个错误'typeA'只指一种类型,但在这里被用作一个值。
解决方案
考虑这个例子:
type typeA = {
name: string
}
type typeB = {
surname: string
}
type typeC = {
age: number
}
type post = typeA | typeB | typeC
interface propTypes {
post: post
}
const App = ({ post }: propTypes) => {
post // no autocomplete
return null
}
之后没有自动完成,post.
因为您没有任何常见的道具。
查看文档
如果我们有一个联合类型的值,我们只能访问联合中所有类型共有的成员。
为了使其工作,您应该定义一个typeguard:
const isTypeA = (props: unknown): props is typeA => Object.prototype.hasOwnProperty.call(props, 'name')
const App = ({ post }: propTypes) => {
if (isTypeA(post)) {
post.name // string
}
return null
}
或者,您可以使用in
运算符,它与联合非常有效:
const App = ({ post }: propTypes) => {
if ('name' in post) {
post.name // string
}
return null
}
或者你可以使用StrictUnion
类型:
type typeA = {
name: string
}
type typeB = {
surname: string
}
type typeC = {
age: number
}
// credits goes to https://stackoverflow.com/questions/65805600/type-union-not-checking-for-excess-properties#answer-65805753
type UnionKeys<T> = T extends T ? keyof T : never;
type StrictUnionHelper<T, TAll> =
T extends any
? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, never>> : never;
type StrictUnion<T> = StrictUnionHelper<T, T>
type Post = StrictUnion<typeA | typeB | typeC>
interface propTypes {
post: Post
}
const App = ({ post }: propTypes) => {
if (post.name) {
post.name // string
}
return null
}
'in' 运算符为我工作请记住,它有自己的缺点:
type typeA = {
name?: string
}
interface propTypes {
post: typeA
}
const App = ({ post }: propTypes) => {
if ('name' in post) {
post.name.charAt // error
}
return null
}
它适用于联合,但不适用于可选属性。
推荐阅读
- javascript - 在外部单击时关闭多个框下拉菜单
- android - 将 Android.mk 转换为 android.bp 时出错
- java - 编译时找不到 Manifest.permission.CAPTURE_VIDEO_OUTPUT,如何解决?
- javascript - 未捕获的类型错误:无法设置未定义的属性“值” // for 和 while 循环的区别?
- reactjs - Webfonts-loader:覆盖同名图标
- java - 使用 s3Client.copyObject 方法复制带有“子目录”的 S3 对象
- c# - Winforms,我可以在这里使用文本框而不是组合框吗?(超过 15k 选项的下拉列表)
- flutter - 如果用户是管理员颤振,则显示一个小部件
- sql - 如何将 SQL 表中的正则表达式匹配到文本
- angular - 打字稿中有没有办法强制类实现/覆盖静态变量?