Skip to content
This repository has been archived by the owner on Jun 21, 2023. It is now read-only.

Commit

Permalink
Fix types for static image (vercel#25808)
Browse files Browse the repository at this point in the history
If you give a Static Image to the Image component, TypeScript will throw a type error. This Pull Request fixes it.

## Bug

- ~~Related issues linked using `fixes #number`~~
- [x] Integration tests added

## ~~Feature~~

- ~~Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.~~
- ~~Related issues linked using `fixes #number`~~
- ~~Integration tests added~~
- ~~Documentation added~~
- ~~Telemetry added. In case of a feature if it's used or not.~~

## ~~Documentation / Examples~~

- ~~Make sure the linting passes~~

---

follow-up vercel#24993
cc @atcastle
  • Loading branch information
ykzts committed Jun 7, 2021
1 parent 80d023c commit 1c63b2d
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 17 deletions.
44 changes: 28 additions & 16 deletions packages/next/client/image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,33 +83,45 @@ function isStaticImport(src: string | StaticImport): src is StaticImport {
)
}

type StringImageProps = {
src: string
} & (
| { width?: never; height?: never; layout: 'fill' }
| {
width: number | string
height: number | string
layout?: Exclude<LayoutValue, 'fill'>
}
) &
(
| {
placeholder?: Exclude<PlaceholderValue, 'blur'>
blurDataURL?: never
}
| { placeholder: 'blur'; blurDataURL: string }
)

type ObjectImageProps = {
src: StaticImport
width?: number | string
height?: number | string
layout?: LayoutValue
placeholder?: PlaceholderValue
blurDataURL?: never
}

export type ImageProps = Omit<
JSX.IntrinsicElements['img'],
'src' | 'srcSet' | 'ref' | 'width' | 'height' | 'loading' | 'style'
> & {
src: string | StaticImport
loader?: ImageLoader
quality?: number | string
priority?: boolean
loading?: LoadingValue
unoptimized?: boolean
objectFit?: ImgElementStyle['objectFit']
objectPosition?: ImgElementStyle['objectPosition']
} & (
| { width?: never; height?: never; layout: 'fill' }
| {
width: number | string
height: number | string
layout?: Exclude<LayoutValue, 'fill'>
}
) &
(
| {
placeholder?: Exclude<PlaceholderValue, 'blur'>
blurDataURL?: never
}
| { placeholder: 'blur'; blurDataURL: string }
)
} & (StringImageProps | ObjectImageProps)

const {
deviceSizes: configDeviceSizes,
Expand Down
55 changes: 55 additions & 0 deletions packages/next/types/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,58 @@ declare module '*.module.scss' {
const classes: { readonly [key: string]: string }
export default classes
}

interface StaticImageData {
src: string
height: number
width: number
placeholder?: string
}

declare module '*.png' {
const content: StaticImageData

export default content
}

declare module '*.svg' {
const content: StaticImageData

export default content
}

declare module '*.jpg' {
const content: StaticImageData

export default content
}

declare module '*.jpeg' {
const content: StaticImageData

export default content
}

declare module '*.gif' {
const content: StaticImageData

export default content
}

declare module '*.webp' {
const content: StaticImageData

export default content
}

declare module '*.ico' {
const content: StaticImageData

export default content
}

declare module '*.bmp' {
const content: StaticImageData

export default content
}
7 changes: 7 additions & 0 deletions test/integration/image-component/typescript/pages/invalid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ const Invalid = () => {
id="no-width-or-height"
src="https://via.placeholder.com/500"
></Image>
<Image
id="no-blur-data-url"
src="https://via.placeholder.com/500"
width={500}
height={500}
placeholder="blur"
></Image>
<p id="stubtext">This is the invalid usage</p>
</div>
)
Expand Down
15 changes: 15 additions & 0 deletions test/integration/image-component/typescript/pages/valid.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react'
import Image from 'next/image'
import testTall from '../public/tall.png'

const Page = () => {
return (
Expand Down Expand Up @@ -58,6 +59,20 @@ const Page = () => {
objectFit="scale-down"
objectPosition="50px"
/>
<Image
id="placeholder-and-blur-data-url"
src="https://via.placeholder.com/500"
width={500}
height={500}
placeholder="blur"
blurDataURL="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="
/>
<Image id="no-width-and-height" src={testTall} />
<Image
id="object-src-with-placeholder"
src={testTall}
placeholder="blur"
/>
<p id="stubtext">This is valid usage of the Image component</p>
</div>
)
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ const runTests = () => {

await browser.back().waitForElementByCss('#another')

expect(await browser.elementByCss('#another').text()).toBe('another page')
expect(await browser.waitForElementByCss('#another').text()).toBe(
'another page'
)

expect(await browser.eval('window.beforeNav')).toBe(1)
})
Expand Down

0 comments on commit 1c63b2d

Please sign in to comment.