From f3b12222f4e517797ca8a80a19aa77955905cf21 Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Sun, 6 Jun 2021 00:05:56 +0900 Subject: [PATCH 1/4] Fix types for static image --- packages/next/client/image.tsx | 46 ++++++++++------ packages/next/types/experimental-images.d.ts | 52 ++++++++++++++++++ .../typescript/pages/invalid.tsx | 7 +++ .../typescript/pages/valid.tsx | 18 +++++- .../typescript/public/tall.png | Bin 0 -> 6391 bytes 5 files changed, 105 insertions(+), 18 deletions(-) create mode 100644 packages/next/types/experimental-images.d.ts create mode 100644 test/integration/image-component/typescript/public/tall.png diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index 121db491f5a1d..712baa3301abc 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -50,7 +50,7 @@ type PlaceholderValue = 'blur' | 'empty' type ImgElementStyle = NonNullable -interface StaticImageData { +export interface StaticImageData { src: string height: number width: number @@ -83,11 +83,37 @@ 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 + } +) & + ( + | { + placeholder?: Exclude + 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 @@ -95,21 +121,7 @@ export type ImageProps = Omit< unoptimized?: boolean objectFit?: ImgElementStyle['objectFit'] objectPosition?: ImgElementStyle['objectPosition'] -} & ( - | { width?: never; height?: never; layout: 'fill' } - | { - width: number | string - height: number | string - layout?: Exclude - } - ) & - ( - | { - placeholder?: Exclude - blurDataURL?: never - } - | { placeholder: 'blur'; blurDataURL: string } - ) +} & (StringImageProps | ObjectImageProps) const { deviceSizes: configDeviceSizes, diff --git a/packages/next/types/experimental-images.d.ts b/packages/next/types/experimental-images.d.ts new file mode 100644 index 0000000000000..4ee8c96d00064 --- /dev/null +++ b/packages/next/types/experimental-images.d.ts @@ -0,0 +1,52 @@ +import { + StaticImageData, + // @ts-ignore This path is generated at build time and conflicts otherwise +} from '../dist/client/image' + +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 +} diff --git a/test/integration/image-component/typescript/pages/invalid.tsx b/test/integration/image-component/typescript/pages/invalid.tsx index 2a1daf83e1186..e39b1d7da3087 100644 --- a/test/integration/image-component/typescript/pages/invalid.tsx +++ b/test/integration/image-component/typescript/pages/invalid.tsx @@ -9,6 +9,13 @@ const Invalid = () => { id="no-width-or-height" src="https://via.placeholder.com/500" > +

This is the invalid usage

) diff --git a/test/integration/image-component/typescript/pages/valid.tsx b/test/integration/image-component/typescript/pages/valid.tsx index 640211ea9c560..a070de2f4ef70 100644 --- a/test/integration/image-component/typescript/pages/valid.tsx +++ b/test/integration/image-component/typescript/pages/valid.tsx @@ -1,5 +1,7 @@ import React from 'react' -import Image from 'next/image' +import Image, { StaticImageData } from 'next/image' +// @ts-ignore This path is generated at build time and conflicts otherwise +import testTall from '../public/tall.png' const Page = () => { return ( @@ -58,6 +60,20 @@ const Page = () => { objectFit="scale-down" objectPosition="50px" /> + + +

This is valid usage of the Image component

) diff --git a/test/integration/image-component/typescript/public/tall.png b/test/integration/image-component/typescript/public/tall.png new file mode 100644 index 0000000000000000000000000000000000000000..a792dda6c172ffb6254d0d82e3a9a8a7cfe4d3e3 GIT binary patch literal 6391 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 Date: Mon, 7 Jun 2021 17:54:31 +0200 Subject: [PATCH 2/4] Fix flaky test --- .../rewrite-with-browser-history/test/index.test.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/integration/rewrite-with-browser-history/test/index.test.js b/test/integration/rewrite-with-browser-history/test/index.test.js index 9d0cf24942409..ee4bb5d8f68f0 100644 --- a/test/integration/rewrite-with-browser-history/test/index.test.js +++ b/test/integration/rewrite-with-browser-history/test/index.test.js @@ -32,7 +32,9 @@ const runTests = () => { await browser.back() - 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) }) From 30d7ef841b9dba3e1ee26ed432203f55f5c67028 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 7 Jun 2021 17:02:03 -0500 Subject: [PATCH 3/4] Update image type handling --- packages/next/types/experimental-images.d.ts | 52 ------------------ packages/next/types/global.d.ts | 55 +++++++++++++++++++ .../typescript/pages/valid.tsx | 7 +-- 3 files changed, 58 insertions(+), 56 deletions(-) delete mode 100644 packages/next/types/experimental-images.d.ts diff --git a/packages/next/types/experimental-images.d.ts b/packages/next/types/experimental-images.d.ts deleted file mode 100644 index 4ee8c96d00064..0000000000000 --- a/packages/next/types/experimental-images.d.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { - StaticImageData, - // @ts-ignore This path is generated at build time and conflicts otherwise -} from '../dist/client/image' - -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 -} diff --git a/packages/next/types/global.d.ts b/packages/next/types/global.d.ts index 706b8a1dbd184..d753639368269 100644 --- a/packages/next/types/global.d.ts +++ b/packages/next/types/global.d.ts @@ -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 +} diff --git a/test/integration/image-component/typescript/pages/valid.tsx b/test/integration/image-component/typescript/pages/valid.tsx index a070de2f4ef70..102f601c3ce4a 100644 --- a/test/integration/image-component/typescript/pages/valid.tsx +++ b/test/integration/image-component/typescript/pages/valid.tsx @@ -1,6 +1,5 @@ import React from 'react' -import Image, { StaticImageData } from 'next/image' -// @ts-ignore This path is generated at build time and conflicts otherwise +import Image from 'next/image' import testTall from '../public/tall.png' const Page = () => { @@ -68,10 +67,10 @@ const Page = () => { placeholder="blur" blurDataURL="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" /> - +

This is valid usage of the Image component

From 42dcfc54dd9845bd772f8e4c7ca1816b84f23eb9 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 7 Jun 2021 17:47:19 -0500 Subject: [PATCH 4/4] un-export type --- packages/next/client/image.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/client/image.tsx b/packages/next/client/image.tsx index 712baa3301abc..1a3e507e59e88 100644 --- a/packages/next/client/image.tsx +++ b/packages/next/client/image.tsx @@ -50,7 +50,7 @@ type PlaceholderValue = 'blur' | 'empty' type ImgElementStyle = NonNullable -export interface StaticImageData { +interface StaticImageData { src: string height: number width: number