typescript 如何使用修复类型字符串中不存在错误“|interface”或者我可以在useState中使用满足吗?

lsmd5eda  于 2022-12-30  发布在  TypeScript
关注(0)|答案(3)|浏览(101)

我有下一个接口

interface ICustomImage {
  data: string;
  width: number;
  height: number;
}

type UserImage = string | ICustomImage

interface IUser {
  id: number;
  firstName: string;
  lastName: string;
  image: UserImage
}

我从API获取IUser并将其存储在useState中,如下所示:

const [user, setUser] = useState<IUser[]>();

但是,当我尝试使用自动完成时,会发生这种情况,而不是显示字符串具有的所有方法或ICustomImage属性

user.image.width //Because I know it comes with width, this error appears

类型“string”上不存在属性“width|类型“string”上不存在属性“width”。
如何修复此问题,或使其可以使用以下内容

user.image.data or user.image.width or user.image.height
o4tp2gmn

o4tp2gmn1#

在访问user.image的属性之前,您必须缩小其类型。如果您不这样做,您将只被允许访问交叉/共享属性toStringvalueOf
你可以这样做:

const someNumber = typeof user.image === 'string' ? user.image.length : user.image.height
9avjhtql

9avjhtql2#

Typescript正在抱怨,因为user.image可以是string类型,因此你无法访问width属性。你需要使用in关键字检查TypeScript中的类型。

if ("width" in user.image) {
    const width = user.image.width; // should be ok
}

因为你必须检查多个属性(高度、数据等),所以你可以定义一个type guard function
如果你绝对确定它的类型是ICustomImage,那么你可以如下所示的转换该值:

const image = user.image as ICustomImage
const width = image.width;

关于州名,它应该是复数(因为它是一个user数组)。

// Multiple users
const [users, setUsers] = useState<IUser[]>();
// Single user
const [user, setUser] = useState<IUser>();
wn9m85ua

wn9m85ua3#

Typescript无法知道image是字符串还是接口对象。您还没有为解释器缩小范围,需要这样做。编写一个类型保护来处理此问题:

interface CustomImage {
    data: string
    width: number
    height: number
}

interface User {
    id: number
    firstName: string
    lastName: string
    image: CustomImage | string
}

const hasCustomImage = (object: any): object is CustomImage => {
    return !!object.data
}

const userCustomImage: User = {
    id: 1,
    firstName: "first",
    lastName: "last",
    image: {
        data: 'data',
        width: 1024,
        height: 768
    }
}

const userStringImage: User = {
    id: 2,
    firstName: "first",
    lastName: "last",
    image: 'image'
}

console.log(`typeguard against custom image object: ${hasCustomImage(userCustomImage.image)}`)
console.log(`typeguard against string image: ${hasCustomImage(userStringImage.image)}`)

const dataImage = hasCustomImage(userCustomImage.image) && userCustomImage.image.data || userCustomImage.image
const stringImage = hasCustomImage(userStringImage.image) && userStringImage.image.data || userCustomImage.image

console.log(dataImage)
console.log(stringImage)

你也可以做一个反向检查,你的类型保护程序检查对象是否是字符串,但这应该会给予你一些指导。

相关问题