简体   繁体   English

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

[英]How to ensure that string refers to an image using typescript?

I have a ReactJs project in which I get the image path through a require in an object. This object has a type and the img property receives a string.我有一个ReactJs project ,其中我通过 object 中的require获取图像路径。这个 object 有一个类型,并且 img 属性接收一个字符串。 It works, but the problem is that TS can't know whether this string is an image or any other thing:它有效,但问题是 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'
}

Is there a way to type img so TS would know which value is really valid?有没有办法输入 img 以便 TS 知道哪个值是真正有效的?

You may want to wrap that require in a function which does some runtime type checking.您可能希望将require包装在 function 中,它会进行一些运行时类型检查。 require returns any anyway. any require退货。

If the type of the img field is a datauri then it is simple.如果img字段的类型是 datauri 那么它很简单。 You can express that as a type:您可以将其表示为一种类型:

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'
}

If it's a path, the way you check whether or not it's valid at runtime is up to you and your level of paranoia.如果它是一条路径,那么您在运行时检查它是否有效的方式取决于您和您的偏执程度。 Maybe you only want to make sure require is used, then you can skip the check, but it's fundamentally the same process:也许你只想确保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'
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM