如何确保字符串引用使用 typescript 的图像?

9gm1akwq  于 2023-01-06  发布在  TypeScript
关注(0)|答案(1)|浏览(97)

我有一个ReactJs project,通过一个对象中的require获取图像路径,这个对象有一个类型,img属性接收一个字符串,它可以工作,但问题是TS无法知道这个字符串是图像还是其他东西:

type Obj = {
  img: string
}

// That's correct
const obj1 = {
  img: require('./../img-path-here')
}

// That's not correct, but TS doesn't complain
const obj2 = {
  img: './../img-path-here'
}

// That's not correct either, but TS doesn't complain
const obj3 = {
  img: 'any string'
}

有没有办法键入img,让TS知道哪个值是真正有效的?

az31mfrm

az31mfrm1#

您可能希望将require Package 在一个函数中,该函数执行一些运行时类型检查。require无论如何都会返回any
如果img字段的类型是一个datauri,那么它就很简单,你可以把它表示为一个类型:

type Base64Image = `data:image/${'jpeg'|'png'|'gif'};base64,${string}`
const base64ImageDecoder = /^data:image\/(jpeg|png|gif);base64,/;

const requireImage = (path: string) => {
    const data = require(path);
    if(typeof data === 'string' && base64ImageDecoder.test(data)) {
        return data as Base64Image
    } else throw Error(`"${path}" doesn't point to a Base64Image`)
}

type Obj = {
    img: Base64Image
}

const obj1: Obj = {
    img: requireImage('./../img-path-here')
}

const obj2: Obj = {
    // @ts-expect-error: not Base64Image
    img: './../img-path-here'
}

如果它是一个路径,那么在运行时检查它是否有效的方式取决于您和您的偏执程度,也许您只想确保使用了require,那么您可以跳过检查,但基本上是相同的过程:

type ImagePath = string & { _tag: 'ImagePath' }
const isImagePath = (data: unknown) => /* you do you */;

const requireImagePath = (path: string) => {
    const data = require(path);
    if(isImagePath(data)) {
        return data as ImagePath
    } else throw Error(`"${path}" doesn't point to an ImagePath`)
}

type Obj = {
    img: ImagePath
}

const obj1: Obj = {
    img: requireImagePath('./../img-path-here')
}

const obj2: Obj = {
    // @ts-expect-error: not ImagePath
    img: './../img-path-here'
}

相关问题