From 812f5134b60bd2817469d99b5301710a2b1ec844 Mon Sep 17 00:00:00 2001 From: Boaris <31354262+boar-is@users.noreply.github.com> Date: Mon, 18 Nov 2024 23:55:46 +0200 Subject: [PATCH 1/4] Implement metadata types support for exactOptionalPropertyTypes --- .../metadata/types/alternative-urls-types.ts | 12 +- .../src/lib/metadata/types/extra-types.ts | 100 ++++---- .../src/lib/metadata/types/manifest-types.ts | 79 +++--- .../lib/metadata/types/metadata-interface.ts | 97 ++++---- .../src/lib/metadata/types/metadata-types.ts | 120 ++++----- .../src/lib/metadata/types/opengraph-types.ts | 232 +++++++++--------- .../src/lib/metadata/types/twitter-types.ts | 52 ++-- 7 files changed, 348 insertions(+), 344 deletions(-) diff --git a/packages/next/src/lib/metadata/types/alternative-urls-types.ts b/packages/next/src/lib/metadata/types/alternative-urls-types.ts index 2155e3cac11e9..483662d8f414b 100644 --- a/packages/next/src/lib/metadata/types/alternative-urls-types.ts +++ b/packages/next/src/lib/metadata/types/alternative-urls-types.ts @@ -427,23 +427,23 @@ type UnmatchedLang = 'x-default' type HrefLang = LangCode | UnmatchedLang export type Languages = { - [s in HrefLang]?: T + [s in HrefLang]?: T | undefined } export type AlternateLinkDescriptor = { - title?: string + title?: string | undefined url: string | URL } export type AlternateURLs = { - canonical?: null | string | URL | AlternateLinkDescriptor - languages?: Languages + canonical?: null | string | URL | AlternateLinkDescriptor | undefined + languages?: Languages | undefined media?: { [media: string]: null | string | URL | AlternateLinkDescriptor[] - } + } | undefined types?: { [types: string]: null | string | URL | AlternateLinkDescriptor[] - } + } | undefined } export type ResolvedAlternateURLs = { diff --git a/packages/next/src/lib/metadata/types/extra-types.ts b/packages/next/src/lib/metadata/types/extra-types.ts index 0afd54a3bfaa6..30379004c51fc 100644 --- a/packages/next/src/lib/metadata/types/extra-types.ts +++ b/packages/next/src/lib/metadata/types/extra-types.ts @@ -3,65 +3,65 @@ // ref: https://developers.facebook.com/docs/applinks/metadata-reference export type AppLinks = { - ios?: AppLinksApple | Array - iphone?: AppLinksApple | Array - ipad?: AppLinksApple | Array - android?: AppLinksAndroid | Array - windows_phone?: AppLinksWindows | Array - windows?: AppLinksWindows | Array - windows_universal?: AppLinksWindows | Array - web?: AppLinksWeb | Array + ios?: AppLinksApple | Array | undefined + iphone?: AppLinksApple | Array | undefined + ipad?: AppLinksApple | Array | undefined + android?: AppLinksAndroid | Array | undefined + windows_phone?: AppLinksWindows | Array | undefined + windows?: AppLinksWindows | Array | undefined + windows_universal?: AppLinksWindows | Array | undefined + web?: AppLinksWeb | Array | undefined } export type ResolvedAppLinks = { - ios?: Array - iphone?: Array - ipad?: Array - android?: Array - windows_phone?: Array - windows?: Array - windows_universal?: Array - web?: Array + ios?: Array | undefined + iphone?: Array | undefined + ipad?: Array | undefined + android?: Array | undefined + windows_phone?: Array | undefined + windows?: Array | undefined + windows_universal?: Array | undefined + web?: Array | undefined } export type AppLinksApple = { url: string | URL - app_store_id?: string | number - app_name?: string + app_store_id?: string | number | undefined + app_name?: string | undefined } export type AppLinksAndroid = { package: string - url?: string | URL - class?: string - app_name?: string + url?: string | URL | undefined + class?: string | undefined + app_name?: string | undefined } export type AppLinksWindows = { url: string | URL - app_id?: string - app_name?: string + app_id?: string | undefined + app_name?: string | undefined } export type AppLinksWeb = { url: string | URL - should_fallback?: boolean + should_fallback?: boolean | undefined } // Apple Itunes APp // https://developer.apple.com/documentation/webkit/promoting_apps_with_smart_app_banners export type ItunesApp = { appId: string - appArgument?: string + appArgument?: string | undefined } // Viewport meta structure // https://developer.mozilla.org/docs/Web/HTML/Viewport_meta_tag // intentionally leaving out user-scalable, use a string if you want that behavior export type ViewportLayout = { - width?: string | number - height?: string | number - initialScale?: number - minimumScale?: number - maximumScale?: number - userScalable?: boolean - viewportFit?: 'auto' | 'cover' | 'contain' - interactiveWidget?: 'resizes-visual' | 'resizes-content' | 'overlays-content' + width?: string | number | undefined + height?: string | number | undefined + initialScale?: number | undefined + minimumScale?: number | undefined + maximumScale?: number | undefined + userScalable?: boolean | undefined + viewportFit?: 'auto' | 'cover' | 'contain' | undefined + interactiveWidget?: 'resizes-visual' | 'resizes-content' | 'overlays-content' | undefined } // Apple Web App @@ -69,37 +69,37 @@ export type ViewportLayout = { // https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/ConfiguringWebApplications/ConfiguringWebApplications.html export type AppleWebApp = { // default true - capable?: boolean - title?: string - startupImage?: AppleImage | Array + capable?: boolean | undefined + title?: string | undefined + startupImage?: AppleImage | Array | undefined // default "default" - statusBarStyle?: 'default' | 'black' | 'black-translucent' + statusBarStyle?: 'default' | 'black' | 'black-translucent' | undefined } export type AppleImage = string | AppleImageDescriptor export type AppleImageDescriptor = { url: string - media?: string + media?: string | undefined } export type ResolvedAppleWebApp = { capable: boolean - title?: string | null - startupImage?: AppleImageDescriptor[] | null - statusBarStyle?: 'default' | 'black' | 'black-translucent' + title?: string | null | undefined + startupImage?: AppleImageDescriptor[] | null | undefined + statusBarStyle?: 'default' | 'black' | 'black-translucent' | undefined } export type Facebook = FacebookAppId | FacebookAdmins export type FacebookAppId = { appId: string - admins?: never + admins?: never | undefined } export type FacebookAdmins = { - appId?: never + appId?: never | undefined admins: string | string[] } export type ResolvedFacebook = { - appId?: string - admins?: string[] + appId?: string | undefined + admins?: string[] | undefined } // Format Detection @@ -110,9 +110,9 @@ export type ResolvedFacebook = { // that can initiate a phone call // https://www.goodemailcode.com/email-code/template.html export type FormatDetection = { - telephone?: boolean - date?: boolean - address?: boolean - email?: boolean - url?: boolean + telephone?: boolean | undefined + date?: boolean | undefined + address?: boolean | undefined + email?: boolean | undefined + url?: boolean | undefined } diff --git a/packages/next/src/lib/metadata/types/manifest-types.ts b/packages/next/src/lib/metadata/types/manifest-types.ts index 719b9d8775caf..f5366dfc75c3e 100644 --- a/packages/next/src/lib/metadata/types/manifest-types.ts +++ b/packages/next/src/lib/metadata/types/manifest-types.ts @@ -11,37 +11,38 @@ type File = { type Icon = { src: string - type?: string - sizes?: string - purpose?: 'any' | 'maskable' | 'monochrome' + type?: string | undefined + sizes?: string | undefined + purpose?: 'any' | 'maskable' | 'monochrome' | undefined } export type Manifest = { - background_color?: string - categories?: string[] - description?: string - dir?: 'ltr' | 'rtl' | 'auto' - display?: 'fullscreen' | 'standalone' | 'minimal-ui' | 'browser' + background_color?: string | undefined + categories?: string[] | undefined + description?: string | undefined + dir?: 'ltr' | 'rtl' | 'auto' | undefined + display?: 'fullscreen' | 'standalone' | 'minimal-ui' | 'browser' | undefined display_override?: ( | 'fullscreen' | 'standalone' | 'minimal-ui' | 'browser' | 'window-controls-overlay' + | undefined )[] file_handlers?: { action: string accept: { [mimeType: string]: string[] } - }[] - icons?: Icon[] - id?: string - lang?: string + }[] | undefined + icons?: Icon[] | undefined + id?: string | undefined + lang?: string | undefined launch_handler?: { client_mode: ClientModeEnum | ClientModeEnum[] - } - name?: string + } | undefined + name?: string | undefined orientation?: | 'any' | 'natural' @@ -51,20 +52,21 @@ export type Manifest = { | 'portrait-secondary' | 'landscape-primary' | 'landscape-secondary' - prefer_related_applications?: boolean + | undefined + prefer_related_applications?: boolean | undefined protocol_handlers?: { protocol: string url: string - }[] + }[] | undefined related_applications?: { platform: string url: string - id?: string - }[] - scope?: string + id?: string | undefined + }[] | undefined + scope?: string | undefined screenshots?: { - form_factor?: 'narrow' | 'wide' - label?: string + form_factor?: 'narrow' | 'wide' | undefined + label?: string | undefined platform?: | 'android' | 'chromeos' @@ -79,29 +81,30 @@ export type Manifest = { | 'microsoft-inbox' | 'microsoft-store' | 'play' + | undefined src: string - type?: string - sizes?: string - }[] + type?: string | undefined + sizes?: string | undefined + }[] | undefined share_target?: { action: string - method?: 'get' | 'post' | 'GET' | 'POST' - enctype?: 'application/x-www-form-urlencoded' | 'multipart/form-data' + method?: 'get' | 'post' | 'GET' | 'POST' | undefined + enctype?: 'application/x-www-form-urlencoded' | 'multipart/form-data' | undefined params: { - title?: string - text?: string - url?: string - files?: File | File[] + title?: string | undefined + text?: string | undefined + url?: string | undefined + files?: File | File[] | undefined } - } - short_name?: string + } | undefined + short_name?: string | undefined shortcuts?: { name: string - short_name?: string - description?: string + short_name?: string | undefined + description?: string | undefined url: string - icons?: Icon[] - }[] - start_url?: string - theme_color?: string + icons?: Icon[] | undefined + }[] | undefined + start_url?: string | undefined + theme_color?: string | undefined } diff --git a/packages/next/src/lib/metadata/types/metadata-interface.ts b/packages/next/src/lib/metadata/types/metadata-interface.ts index f81acdb8582bc..01aa883604db8 100644 --- a/packages/next/src/lib/metadata/types/metadata-interface.ts +++ b/packages/next/src/lib/metadata/types/metadata-interface.ts @@ -44,7 +44,7 @@ interface Metadata extends DeprecatedMetadataFields { /** * The base path and origin for absolute urls for various metadata links such as OpenGraph images. */ - metadataBase?: null | URL + metadataBase?: null | URL | undefined /** * The document title. @@ -60,7 +60,7 @@ interface Metadata extends DeprecatedMetadataFields { * My Blog * ``` */ - title?: null | string | TemplateString + title?: null | string | TemplateString | undefined /** * The document description, and optionally the OpenGraph and twitter descriptions. @@ -70,7 +70,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - description?: null | string + description?: null | string | undefined // Standard metadata names // https://developer.mozilla.org/docs/Web/HTML/Element/meta/name @@ -83,7 +83,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - applicationName?: null | string + applicationName?: null | string | undefined /** * The authors of the document. @@ -95,7 +95,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - authors?: null | Author | Array + authors?: null | Author | Array | undefined /** * The generator used for the document. @@ -106,7 +106,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - generator?: null | string + generator?: null | string | undefined /** * The keywords for the document. If an array is provided, it will be flattened into a single tag with comma separation. @@ -119,7 +119,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - keywords?: null | string | Array + keywords?: null | string | Array | undefined /** * The referrer setting for the document. @@ -129,7 +129,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - referrer?: null | ReferrerEnum + referrer?: null | ReferrerEnum | undefined /** * The theme color for the document. @@ -151,7 +151,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - themeColor?: null | string | ThemeColorDescriptor | ThemeColorDescriptor[] + themeColor?: null | string | ThemeColorDescriptor | ThemeColorDescriptor[] | undefined /** * The color scheme for the document. @@ -163,7 +163,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - colorScheme?: null | ColorSchemeEnum + colorScheme?: null | ColorSchemeEnum | undefined /** * The viewport setting for the document. @@ -175,7 +175,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - viewport?: null | string | ViewportLayout + viewport?: null | string | ViewportLayout | undefined /** * The creator of the document. @@ -185,7 +185,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - creator?: null | string + creator?: null | string | undefined /** * The publisher of the document. @@ -196,7 +196,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - publisher?: null | string + publisher?: null | string | undefined // https://developer.mozilla.org/docs/Web/HTML/Element/meta/name#other_metadata_names @@ -213,7 +213,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - robots?: null | string | Robots + robots?: null | string | Robots | undefined /** * The canonical and alternate URLs for the document. @@ -243,7 +243,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - alternates?: null | AlternateURLs + alternates?: null | AlternateURLs | undefined /** * The icons for the document. Defaults to rel="icon". @@ -263,7 +263,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - icons?: null | IconURL | Array | Icons + icons?: null | IconURL | Array | Icons | undefined /** * A web application manifest, as defined in the Web Application Manifest specification. @@ -276,7 +276,7 @@ interface Metadata extends DeprecatedMetadataFields { * ``` * */ - manifest?: null | string | URL + manifest?: null | string | URL | undefined /** * The Open Graph metadata for the document. @@ -303,7 +303,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - openGraph?: null | OpenGraph + openGraph?: null | OpenGraph | undefined /** * The Twitter metadata for the document. @@ -320,7 +320,7 @@ interface Metadata extends DeprecatedMetadataFields { * ``` * */ - twitter?: null | Twitter + twitter?: null | Twitter | undefined /** * The Facebook metadata for the document. @@ -339,7 +339,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - facebook?: null | Facebook + facebook?: null | Facebook | undefined /** * The common verification tokens for the document. @@ -351,7 +351,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - verification?: Verification + verification?: Verification | undefined /** * The Apple web app metadata for the document. @@ -366,7 +366,7 @@ interface Metadata extends DeprecatedMetadataFields { * ``` * */ - appleWebApp?: null | boolean | AppleWebApp + appleWebApp?: null | boolean | AppleWebApp | undefined /** * Indicates if devices should try to interpret various formats and make actionable links out of them. For example it controles @@ -378,7 +378,7 @@ interface Metadata extends DeprecatedMetadataFields { * ``` * */ - formatDetection?: null | FormatDetection + formatDetection?: null | FormatDetection | undefined /** * The metadata for the iTunes App. @@ -390,7 +390,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - itunes?: null | ItunesApp + itunes?: null | ItunesApp | undefined /** * A brief description of what this web-page is about. Not recommended, superseded by description. @@ -403,7 +403,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - abstract?: null | string + abstract?: null | string | undefined /** * The Facebook AppLinks metadata for the document. @@ -417,7 +417,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - appLinks?: null | AppLinks + appLinks?: null | AppLinks | undefined /** * The archives link rel property. @@ -427,7 +427,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - archives?: null | string | Array + archives?: null | string | Array | undefined /** * The assets link rel property. @@ -437,7 +437,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - assets?: null | string | Array + assets?: null | string | Array | undefined /** * The bookmarks link rel property. @@ -447,7 +447,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - bookmarks?: null | string | Array // This is technically against HTML spec but is used in wild + bookmarks?: null | string | Array | undefined // This is technically against HTML spec but is used in wild // meta name properties @@ -459,7 +459,7 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - category?: null | string + category?: null | string | undefined /** * The classification meta name property. @@ -469,14 +469,14 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - classification?: null | string + classification?: null | string | undefined /** * Arbitrary name/value pairs for the document. */ other?: { [name: string]: string | number | Array - } & DeprecatedMetadataFields + } & DeprecatedMetadataFields | undefined } interface ResolvedMetadata extends DeprecatedMetadataFields { @@ -576,25 +576,25 @@ type RobotsFile = { // Apply rules for all rules: | { - userAgent?: string | string[] - allow?: string | string[] - disallow?: string | string[] - crawlDelay?: number + userAgent?: string | string[] | undefined + allow?: string | string[] | undefined + disallow?: string | string[] | undefined + crawlDelay?: number | undefined } // Apply rules for specific user agents | Array<{ userAgent: string | string[] - allow?: string | string[] - disallow?: string | string[] - crawlDelay?: number + allow?: string | string[] | undefined + disallow?: string | string[] | undefined + crawlDelay?: number | undefined }> - sitemap?: string | string[] - host?: string + sitemap?: string | string[] | undefined + host?: string | undefined } type SitemapFile = Array<{ url: string - lastModified?: string | Date + lastModified?: string | Date | undefined changeFrequency?: | 'always' | 'hourly' @@ -603,12 +603,13 @@ type SitemapFile = Array<{ | 'monthly' | 'yearly' | 'never' - priority?: number + | undefined + priority?: number | undefined alternates?: { - languages?: Languages - } - images?: string[] - videos?: Videos[] + languages?: Languages | undefined + } | undefined + images?: string[] | undefined + videos?: Videos[] | undefined }> type ResolvingMetadata = Promise @@ -650,7 +651,7 @@ interface Viewport extends ViewportLayout { * * ``` */ - colorScheme?: null | ColorSchemeEnum + colorScheme?: null | ColorSchemeEnum | undefined } type ResolvingViewport = Promise diff --git a/packages/next/src/lib/metadata/types/metadata-types.ts b/packages/next/src/lib/metadata/types/metadata-types.ts index f955ac9858d9d..3e095911c26be 100644 --- a/packages/next/src/lib/metadata/types/metadata-types.ts +++ b/packages/next/src/lib/metadata/types/metadata-types.ts @@ -9,14 +9,14 @@ export interface DeprecatedMetadataFields { * Deprecated options that have a preferred method * @deprecated Use appWebApp to configure mobile-web-app-capable which provides */ - 'apple-touch-fullscreen'?: never + 'apple-touch-fullscreen'?: never | undefined /** * Obsolete since iOS 7. * @see https://web.dev/apple-touch-icon/ * @deprecated use icons.apple or instead */ - 'apple-touch-icon-precomposed'?: never + 'apple-touch-icon-precomposed'?: never | undefined } export type TemplateString = @@ -37,9 +37,9 @@ export type AbsoluteString = { export type Author = { // renders as - phoneNumbers?: string | Array - faxNumbers?: string | Array - siteName?: string - locale?: Locale - alternateLocale?: Locale | Array - images?: OGImage | Array - audio?: OGAudio | Array - videos?: OGVideo | Array - url?: string | URL - countryName?: string - ttl?: number + determiner?: 'a' | 'an' | 'the' | 'auto' | '' | undefined + title?: string | TemplateString | undefined + description?: string | undefined + emails?: string | Array | undefined + phoneNumbers?: string | Array | undefined + faxNumbers?: string | Array | undefined + siteName?: string | undefined + locale?: Locale | undefined + alternateLocale?: Locale | Array | undefined + images?: OGImage | Array | undefined + audio?: OGAudio | Array | undefined + videos?: OGVideo | Array | undefined + url?: string | URL | undefined + countryName?: string | undefined + ttl?: number | undefined } type OpenGraphWebsite = OpenGraphMetadata & { type: 'website' } type OpenGraphArticle = OpenGraphMetadata & { type: 'article' - publishedTime?: string // datetime - modifiedTime?: string // datetime - expirationTime?: string // datetime - authors?: null | string | URL | Array - section?: null | string - tags?: null | string | Array + publishedTime?: string | undefined // datetime + modifiedTime?: string | undefined // datetime + expirationTime?: string | undefined // datetime + authors?: null | string | URL | Array | undefined + section?: null | string | undefined + tags?: null | string | Array | undefined } type OpenGraphBook = OpenGraphMetadata & { type: 'book' - isbn?: null | string - releaseDate?: null | string // datetime - authors?: null | string | URL | Array - tags?: null | string | Array + isbn?: null | string | undefined + releaseDate?: null | string | undefined // datetime + authors?: null | string | URL | Array | undefined + tags?: null | string | Array | undefined } type OpenGraphProfile = OpenGraphMetadata & { type: 'profile' - firstName?: null | string - lastName?: null | string - username?: null | string - gender?: null | string + firstName?: null | string | undefined + lastName?: null | string | undefined + username?: null | string | undefined + gender?: null | string | undefined } type OpenGraphMusicSong = OpenGraphMetadata & { type: 'music.song' - duration?: null | number - albums?: null | string | URL | OGAlbum | Array - musicians?: null | string | URL | Array + duration?: null | number | undefined + albums?: null | string | URL | OGAlbum | Array | undefined + musicians?: null | string | URL | Array | undefined } type OpenGraphMusicAlbum = OpenGraphMetadata & { type: 'music.album' - songs?: null | string | URL | OGSong | Array - musicians?: null | string | URL | Array - releaseDate?: null | string // datetime + songs?: null | string | URL | OGSong | Array | undefined + musicians?: null | string | URL | Array | undefined + releaseDate?: null | string | undefined // datetime } type OpenGraphMusicPlaylist = OpenGraphMetadata & { type: 'music.playlist' - songs?: null | string | URL | OGSong | Array - creators?: null | string | URL | Array + songs?: null | string | URL | OGSong | Array | undefined + creators?: null | string | URL | Array | undefined } type OpenGraphRadioStation = OpenGraphMetadata & { type: 'music.radio_station' - creators?: null | string | URL | Array + creators?: null | string | URL | Array | undefined } type OpenGraphVideoMovie = OpenGraphMetadata & { type: 'video.movie' - actors?: null | string | URL | OGActor | Array - directors?: null | string | URL | Array - writers?: null | string | URL | Array - duration?: null | number - releaseDate?: null | string // datetime - tags?: null | string | Array + actors?: null | string | URL | OGActor | Array | undefined + directors?: null | string | URL | Array | undefined + writers?: null | string | URL | Array | undefined + duration?: null | number | undefined + releaseDate?: null | string | undefined // datetime + tags?: null | string | Array | undefined } type OpenGraphVideoEpisode = OpenGraphMetadata & { type: 'video.episode' - actors?: null | string | URL | OGActor | Array - directors?: null | string | URL | Array - writers?: null | string | URL | Array - duration?: null | number - releaseDate?: null | string // datetime - tags?: null | string | Array - series?: null | string | URL + actors?: null | string | URL | OGActor | Array | undefined + directors?: null | string | URL | Array | undefined + writers?: null | string | URL | Array | undefined + duration?: null | number | undefined + releaseDate?: null | string | undefined // datetime + tags?: null | string | Array | undefined + series?: null | string | URL | undefined } type OpenGraphVideoTVShow = OpenGraphMetadata & { type: 'video.tv_show' @@ -125,25 +125,25 @@ type OpenGraphVideoOther = OpenGraphMetadata & { type OGImage = string | OGImageDescriptor | URL type OGImageDescriptor = { url: string | URL - secureUrl?: string | URL - alt?: string - type?: string - width?: string | number - height?: string | number + secureUrl?: string | URL | undefined + alt?: string | undefined + type?: string | undefined + width?: string | number | undefined + height?: string | number | undefined } type OGAudio = string | OGAudioDescriptor | URL type OGAudioDescriptor = { url: string | URL - secureUrl?: string | URL - type?: string + secureUrl?: string | URL | undefined + type?: string | undefined } type OGVideo = string | OGVideoDescriptor | URL type OGVideoDescriptor = { url: string | URL - secureUrl?: string | URL - type?: string - width?: string | number - height?: string | number + secureUrl?: string | URL | undefined + type?: string | undefined + width?: string | number | undefined + height?: string | number | undefined } export type ResolvedOpenGraph = @@ -162,87 +162,87 @@ export type ResolvedOpenGraph = | ResolvedOpenGraphMetadata type ResolvedOpenGraphMetadata = { - determiner?: 'a' | 'an' | 'the' | 'auto' | '' + determiner?: 'a' | 'an' | 'the' | 'auto' | '' | undefined title: AbsoluteTemplateString - description?: string - emails?: Array - phoneNumbers?: Array - faxNumbers?: Array - siteName?: string - locale?: Locale - alternateLocale?: Array - images?: Array - audio?: Array - videos?: Array + description?: string | undefined + emails?: Array | undefined + phoneNumbers?: Array | undefined + faxNumbers?: Array | undefined + siteName?: string | undefined + locale?: Locale | undefined + alternateLocale?: Array | undefined + images?: Array | undefined + audio?: Array | undefined + videos?: Array | undefined url: null | URL | string - countryName?: string - ttl?: number + countryName?: string | undefined + ttl?: number | undefined } type ResolvedOpenGraphWebsite = ResolvedOpenGraphMetadata & { type: 'website' } type ResolvedOpenGraphArticle = ResolvedOpenGraphMetadata & { type: 'article' - publishedTime?: string // datetime - modifiedTime?: string // datetime - expirationTime?: string // datetime - authors?: Array - section?: string - tags?: Array + publishedTime?: string | undefined // datetime + modifiedTime?: string | undefined // datetime + expirationTime?: string | undefined // datetime + authors?: Array | undefined + section?: string | undefined + tags?: Array | undefined } type ResolvedOpenGraphBook = ResolvedOpenGraphMetadata & { type: 'book' - isbn?: string - releaseDate?: string // datetime - authors?: Array - tags?: Array + isbn?: string | undefined + releaseDate?: string | undefined // datetime + authors?: Array | undefined + tags?: Array | undefined } type ResolvedOpenGraphProfile = ResolvedOpenGraphMetadata & { type: 'profile' - firstName?: string - lastName?: string - username?: string - gender?: string + firstName?: string | undefined + lastName?: string | undefined + username?: string | undefined + gender?: string | undefined } type ResolvedOpenGraphMusicSong = ResolvedOpenGraphMetadata & { type: 'music.song' - duration?: number - albums?: Array - musicians?: Array + duration?: number | undefined + albums?: Array | undefined + musicians?: Array | undefined } type ResolvedOpenGraphMusicAlbum = ResolvedOpenGraphMetadata & { type: 'music.album' - songs?: Array - musicians?: Array - releaseDate?: string // datetime + songs?: Array | undefined + musicians?: Array | undefined + releaseDate?: string | undefined // datetime } type ResolvedOpenGraphMusicPlaylist = ResolvedOpenGraphMetadata & { type: 'music.playlist' - songs?: Array - creators?: Array + songs?: Array | undefined + creators?: Array | undefined } type ResolvedOpenGraphRadioStation = ResolvedOpenGraphMetadata & { type: 'music.radio_station' - creators?: Array + creators?: Array | undefined } type ResolvedOpenGraphVideoMovie = ResolvedOpenGraphMetadata & { type: 'video.movie' - actors?: Array - directors?: Array - writers?: Array - duration?: number - releaseDate?: string // datetime - tags?: Array + actors?: Array | undefined + directors?: Array | undefined + writers?: Array | undefined + duration?: number | undefined + releaseDate?: string | undefined // datetime + tags?: Array | undefined } type ResolvedOpenGraphVideoEpisode = ResolvedOpenGraphMetadata & { type: 'video.episode' - actors?: Array - directors?: Array - writers?: Array - duration?: number - releaseDate?: string // datetime - tags?: Array - series?: string | URL + actors?: Array | undefined + directors?: Array | undefined + writers?: Array | undefined + duration?: number | undefined + releaseDate?: string | undefined // datetime + tags?: Array | undefined + series?: string | URL | undefined } type ResolvedOpenGraphVideoTVShow = ResolvedOpenGraphMetadata & { type: 'video.tv_show' @@ -253,15 +253,15 @@ type ResolvedOpenGraphVideoOther = ResolvedOpenGraphMetadata & { type OGSong = { url: string | URL - disc?: number - track?: number + disc?: number | undefined + track?: number | undefined } type OGAlbum = { url: string | URL - disc?: number - track?: number + disc?: number | undefined + track?: number | undefined } type OGActor = { url: string | URL - role?: string + role?: string | undefined } diff --git a/packages/next/src/lib/metadata/types/twitter-types.ts b/packages/next/src/lib/metadata/types/twitter-types.ts index 6bd44173bb21d..228174e1293b7 100644 --- a/packages/next/src/lib/metadata/types/twitter-types.ts +++ b/packages/next/src/lib/metadata/types/twitter-types.ts @@ -11,13 +11,13 @@ export type Twitter = type TwitterMetadata = { // defaults to card="summary" - site?: string // username for account associated to the site itself - siteId?: string // id for account associated to the site itself - creator?: string // username for the account associated to the creator of the content on the site - creatorId?: string // id for the account associated to the creator of the content on the site - description?: string - title?: string | TemplateString - images?: TwitterImage | Array + site?: string | undefined // username for account associated to the site itself + siteId?: string | undefined // id for account associated to the site itself + creator?: string | undefined // username for the account associated to the creator of the content on the site + creatorId?: string | undefined // id for the account associated to the creator of the content on the site + description?: string | undefined + title?: string | TemplateString | undefined + images?: TwitterImage | Array | undefined } type TwitterSummary = TwitterMetadata & { card: 'summary' @@ -35,26 +35,26 @@ type TwitterApp = TwitterMetadata & { } export type TwitterAppDescriptor = { id: { - iphone?: string | number - ipad?: string | number - googleplay?: string + iphone?: string | number | undefined + ipad?: string | number | undefined + googleplay?: string | undefined } url?: { - iphone?: string | URL - ipad?: string | URL - googleplay?: string | URL - } - name?: string + iphone?: string | URL | undefined + ipad?: string | URL | undefined + googleplay?: string | URL | undefined + } | undefined + name?: string | undefined } type TwitterImage = string | TwitterImageDescriptor | URL type TwitterImageDescriptor = { url: string | URL - alt?: string - secureUrl?: string | URL - type?: string - width?: string | number - height?: string | number + alt?: string | undefined + secureUrl?: string | URL | undefined + type?: string | undefined + width?: string | number | undefined + height?: string | number | undefined } type TwitterPlayerDescriptor = { playerUrl: string | URL @@ -65,11 +65,11 @@ type TwitterPlayerDescriptor = { type ResolvedTwitterImage = { url: string | URL - alt?: string - secureUrl?: string | URL - type?: string - width?: string | number - height?: string | number + alt?: string | undefined + secureUrl?: string | URL | undefined + type?: string | undefined + width?: string | number | undefined + height?: string | number | undefined } type ResolvedTwitterSummary = { site: string | null @@ -78,7 +78,7 @@ type ResolvedTwitterSummary = { creatorId: string | null description: string | null title: AbsoluteTemplateString - images?: Array + images?: Array | undefined } type ResolvedTwitterPlayer = ResolvedTwitterSummary & { players: Array From 52eb4465e4ae5a2e19e9467d4648a2bbe52a728a Mon Sep 17 00:00:00 2001 From: Boaris Date: Tue, 19 Nov 2024 22:13:24 +0200 Subject: [PATCH 2/4] Run Prettier --- .../metadata/types/alternative-urls-types.ts | 20 ++- .../src/lib/metadata/types/extra-types.ts | 6 +- .../src/lib/metadata/types/manifest-types.ts | 133 ++++++++++-------- .../lib/metadata/types/metadata-interface.ts | 23 ++- .../src/lib/metadata/types/metadata-types.ts | 26 ++-- .../src/lib/metadata/types/opengraph-types.ts | 40 +++++- .../src/lib/metadata/types/twitter-types.ts | 12 +- 7 files changed, 167 insertions(+), 93 deletions(-) diff --git a/packages/next/src/lib/metadata/types/alternative-urls-types.ts b/packages/next/src/lib/metadata/types/alternative-urls-types.ts index 483662d8f414b..a3d0f329e8d8a 100644 --- a/packages/next/src/lib/metadata/types/alternative-urls-types.ts +++ b/packages/next/src/lib/metadata/types/alternative-urls-types.ts @@ -437,13 +437,19 @@ export type AlternateLinkDescriptor = { export type AlternateURLs = { canonical?: null | string | URL | AlternateLinkDescriptor | undefined - languages?: Languages | undefined - media?: { - [media: string]: null | string | URL | AlternateLinkDescriptor[] - } | undefined - types?: { - [types: string]: null | string | URL | AlternateLinkDescriptor[] - } | undefined + languages?: + | Languages + | undefined + media?: + | { + [media: string]: null | string | URL | AlternateLinkDescriptor[] + } + | undefined + types?: + | { + [types: string]: null | string | URL | AlternateLinkDescriptor[] + } + | undefined } export type ResolvedAlternateURLs = { diff --git a/packages/next/src/lib/metadata/types/extra-types.ts b/packages/next/src/lib/metadata/types/extra-types.ts index 30379004c51fc..c987e1512eecb 100644 --- a/packages/next/src/lib/metadata/types/extra-types.ts +++ b/packages/next/src/lib/metadata/types/extra-types.ts @@ -61,7 +61,11 @@ export type ViewportLayout = { maximumScale?: number | undefined userScalable?: boolean | undefined viewportFit?: 'auto' | 'cover' | 'contain' | undefined - interactiveWidget?: 'resizes-visual' | 'resizes-content' | 'overlays-content' | undefined + interactiveWidget?: + | 'resizes-visual' + | 'resizes-content' + | 'overlays-content' + | undefined } // Apple Web App diff --git a/packages/next/src/lib/metadata/types/manifest-types.ts b/packages/next/src/lib/metadata/types/manifest-types.ts index f5366dfc75c3e..355f8711a0b64 100644 --- a/packages/next/src/lib/metadata/types/manifest-types.ts +++ b/packages/next/src/lib/metadata/types/manifest-types.ts @@ -30,18 +30,22 @@ export type Manifest = { | 'window-controls-overlay' | undefined )[] - file_handlers?: { - action: string - accept: { - [mimeType: string]: string[] - } - }[] | undefined + file_handlers?: + | { + action: string + accept: { + [mimeType: string]: string[] + } + }[] + | undefined icons?: Icon[] | undefined id?: string | undefined lang?: string | undefined - launch_handler?: { - client_mode: ClientModeEnum | ClientModeEnum[] - } | undefined + launch_handler?: + | { + client_mode: ClientModeEnum | ClientModeEnum[] + } + | undefined name?: string | undefined orientation?: | 'any' @@ -54,57 +58,70 @@ export type Manifest = { | 'landscape-secondary' | undefined prefer_related_applications?: boolean | undefined - protocol_handlers?: { - protocol: string - url: string - }[] | undefined - related_applications?: { - platform: string - url: string - id?: string | undefined - }[] | undefined + protocol_handlers?: + | { + protocol: string + url: string + }[] + | undefined + related_applications?: + | { + platform: string + url: string + id?: string | undefined + }[] + | undefined scope?: string | undefined - screenshots?: { - form_factor?: 'narrow' | 'wide' | undefined - label?: string | undefined - platform?: - | 'android' - | 'chromeos' - | 'ipados' - | 'ios' - | 'kaios' - | 'macos' - | 'windows' - | 'xbox' - | 'chrome_web_store' - | 'itunes' - | 'microsoft-inbox' - | 'microsoft-store' - | 'play' - | undefined - src: string - type?: string | undefined - sizes?: string | undefined - }[] | undefined - share_target?: { - action: string - method?: 'get' | 'post' | 'GET' | 'POST' | undefined - enctype?: 'application/x-www-form-urlencoded' | 'multipart/form-data' | undefined - params: { - title?: string | undefined - text?: string | undefined - url?: string | undefined - files?: File | File[] | undefined - } - } | undefined + screenshots?: + | { + form_factor?: 'narrow' | 'wide' | undefined + label?: string | undefined + platform?: + | 'android' + | 'chromeos' + | 'ipados' + | 'ios' + | 'kaios' + | 'macos' + | 'windows' + | 'xbox' + | 'chrome_web_store' + | 'itunes' + | 'microsoft-inbox' + | 'microsoft-store' + | 'play' + | undefined + src: string + type?: string | undefined + sizes?: string | undefined + }[] + | undefined + share_target?: + | { + action: string + method?: 'get' | 'post' | 'GET' | 'POST' | undefined + enctype?: + | 'application/x-www-form-urlencoded' + | 'multipart/form-data' + | undefined + params: { + title?: string | undefined + text?: string | undefined + url?: string | undefined + files?: File | File[] | undefined + } + } + | undefined short_name?: string | undefined - shortcuts?: { - name: string - short_name?: string | undefined - description?: string | undefined - url: string - icons?: Icon[] | undefined - }[] | undefined + shortcuts?: + | { + name: string + short_name?: string | undefined + description?: string | undefined + url: string + icons?: Icon[] | undefined + }[] + | undefined start_url?: string | undefined theme_color?: string | undefined } diff --git a/packages/next/src/lib/metadata/types/metadata-interface.ts b/packages/next/src/lib/metadata/types/metadata-interface.ts index 01aa883604db8..57b8b01c3b84c 100644 --- a/packages/next/src/lib/metadata/types/metadata-interface.ts +++ b/packages/next/src/lib/metadata/types/metadata-interface.ts @@ -151,7 +151,12 @@ interface Metadata extends DeprecatedMetadataFields { * * ``` */ - themeColor?: null | string | ThemeColorDescriptor | ThemeColorDescriptor[] | undefined + themeColor?: + | null + | string + | ThemeColorDescriptor + | ThemeColorDescriptor[] + | undefined /** * The color scheme for the document. @@ -474,9 +479,11 @@ interface Metadata extends DeprecatedMetadataFields { /** * Arbitrary name/value pairs for the document. */ - other?: { - [name: string]: string | number | Array - } & DeprecatedMetadataFields | undefined + other?: + | ({ + [name: string]: string | number | Array + } & DeprecatedMetadataFields) + | undefined } interface ResolvedMetadata extends DeprecatedMetadataFields { @@ -605,9 +612,11 @@ type SitemapFile = Array<{ | 'never' | undefined priority?: number | undefined - alternates?: { - languages?: Languages | undefined - } | undefined + alternates?: + | { + languages?: Languages | undefined + } + | undefined images?: string[] | undefined videos?: Videos[] | undefined }> diff --git a/packages/next/src/lib/metadata/types/metadata-types.ts b/packages/next/src/lib/metadata/types/metadata-types.ts index 3e095911c26be..1843a5459895b 100644 --- a/packages/next/src/lib/metadata/types/metadata-types.ts +++ b/packages/next/src/lib/metadata/types/metadata-types.ts @@ -129,9 +129,11 @@ export type Verification = { yandex?: null | string | number | (string | number)[] | undefined me?: null | string | number | (string | number)[] | undefined // if you ad-hoc additional verification - other?: { - [name: string]: string | number | (string | number)[] - } | undefined + other?: + | { + [name: string]: string | number | (string | number)[] + } + | undefined } export type ResolvedVerification = { @@ -139,9 +141,11 @@ export type ResolvedVerification = { yahoo?: null | (string | number)[] | undefined yandex?: null | (string | number)[] | undefined me?: null | (string | number)[] | undefined - other?: { - [name: string]: (string | number)[] - } | undefined + other?: + | { + [name: string]: (string | number)[] + } + | undefined } export type ResolvedIcons = { @@ -176,10 +180,12 @@ export type Videos = { restriction?: Restriction | undefined platform?: Restriction | undefined requires_subscription?: 'yes' | 'no' | undefined - uploader?: { - info?: string | undefined - content?: string | undefined - } | undefined + uploader?: + | { + info?: string | undefined + content?: string | undefined + } + | undefined live?: 'yes' | 'no' | undefined tag?: string | undefined } diff --git a/packages/next/src/lib/metadata/types/opengraph-types.ts b/packages/next/src/lib/metadata/types/opengraph-types.ts index 2d670cd9f8485..76b4cbd6126bf 100644 --- a/packages/next/src/lib/metadata/types/opengraph-types.ts +++ b/packages/next/src/lib/metadata/types/opengraph-types.ts @@ -78,18 +78,36 @@ type OpenGraphProfile = OpenGraphMetadata & { type OpenGraphMusicSong = OpenGraphMetadata & { type: 'music.song' duration?: null | number | undefined - albums?: null | string | URL | OGAlbum | Array | undefined + albums?: + | null + | string + | URL + | OGAlbum + | Array + | undefined musicians?: null | string | URL | Array | undefined } type OpenGraphMusicAlbum = OpenGraphMetadata & { type: 'music.album' - songs?: null | string | URL | OGSong | Array | undefined + songs?: + | null + | string + | URL + | OGSong + | Array + | undefined musicians?: null | string | URL | Array | undefined releaseDate?: null | string | undefined // datetime } type OpenGraphMusicPlaylist = OpenGraphMetadata & { type: 'music.playlist' - songs?: null | string | URL | OGSong | Array | undefined + songs?: + | null + | string + | URL + | OGSong + | Array + | undefined creators?: null | string | URL | Array | undefined } type OpenGraphRadioStation = OpenGraphMetadata & { @@ -98,7 +116,13 @@ type OpenGraphRadioStation = OpenGraphMetadata & { } type OpenGraphVideoMovie = OpenGraphMetadata & { type: 'video.movie' - actors?: null | string | URL | OGActor | Array | undefined + actors?: + | null + | string + | URL + | OGActor + | Array + | undefined directors?: null | string | URL | Array | undefined writers?: null | string | URL | Array | undefined duration?: null | number | undefined @@ -107,7 +131,13 @@ type OpenGraphVideoMovie = OpenGraphMetadata & { } type OpenGraphVideoEpisode = OpenGraphMetadata & { type: 'video.episode' - actors?: null | string | URL | OGActor | Array | undefined + actors?: + | null + | string + | URL + | OGActor + | Array + | undefined directors?: null | string | URL | Array | undefined writers?: null | string | URL | Array | undefined duration?: null | number | undefined diff --git a/packages/next/src/lib/metadata/types/twitter-types.ts b/packages/next/src/lib/metadata/types/twitter-types.ts index 228174e1293b7..2300c9e572f71 100644 --- a/packages/next/src/lib/metadata/types/twitter-types.ts +++ b/packages/next/src/lib/metadata/types/twitter-types.ts @@ -39,11 +39,13 @@ export type TwitterAppDescriptor = { ipad?: string | number | undefined googleplay?: string | undefined } - url?: { - iphone?: string | URL | undefined - ipad?: string | URL | undefined - googleplay?: string | URL | undefined - } | undefined + url?: + | { + iphone?: string | URL | undefined + ipad?: string | URL | undefined + googleplay?: string | URL | undefined + } + | undefined name?: string | undefined } From f4837d261fb2cde18cff6ae7d8b3b270be02426c Mon Sep 17 00:00:00 2001 From: Boaris Date: Wed, 20 Nov 2024 00:04:07 +0200 Subject: [PATCH 3/4] Add typechecking objects with undefined --- .../src/lib/metadata/types/manifest-types.ts | 15 +- .../lib/metadata/types/metadata-interface.ts | 7 +- .../typescript-basic/typechecking/metadata.ts | 737 ++++++++++++++++++ 3 files changed, 751 insertions(+), 8 deletions(-) create mode 100644 test/production/typescript-basic/typechecking/metadata.ts diff --git a/packages/next/src/lib/metadata/types/manifest-types.ts b/packages/next/src/lib/metadata/types/manifest-types.ts index 355f8711a0b64..de96e602b0dc1 100644 --- a/packages/next/src/lib/metadata/types/manifest-types.ts +++ b/packages/next/src/lib/metadata/types/manifest-types.ts @@ -22,14 +22,15 @@ export type Manifest = { description?: string | undefined dir?: 'ltr' | 'rtl' | 'auto' | undefined display?: 'fullscreen' | 'standalone' | 'minimal-ui' | 'browser' | undefined - display_override?: ( - | 'fullscreen' - | 'standalone' - | 'minimal-ui' - | 'browser' - | 'window-controls-overlay' + display_override?: + | ( + | 'fullscreen' + | 'standalone' + | 'minimal-ui' + | 'browser' + | 'window-controls-overlay' + )[] | undefined - )[] file_handlers?: | { action: string diff --git a/packages/next/src/lib/metadata/types/metadata-interface.ts b/packages/next/src/lib/metadata/types/metadata-interface.ts index 57b8b01c3b84c..cf4a408f2ee39 100644 --- a/packages/next/src/lib/metadata/types/metadata-interface.ts +++ b/packages/next/src/lib/metadata/types/metadata-interface.ts @@ -649,7 +649,12 @@ interface Viewport extends ViewportLayout { * * ``` */ - themeColor?: null | string | ThemeColorDescriptor | ThemeColorDescriptor[] + themeColor?: + | null + | string + | ThemeColorDescriptor + | ThemeColorDescriptor[] + | undefined /** * The color scheme for the document. diff --git a/test/production/typescript-basic/typechecking/metadata.ts b/test/production/typescript-basic/typechecking/metadata.ts new file mode 100644 index 0000000000000..98e39c235d687 --- /dev/null +++ b/test/production/typescript-basic/typechecking/metadata.ts @@ -0,0 +1,737 @@ +// noinspection BadExpressionStatementJS,ES6PreferShortImport + +import { + AppleImageDescriptor, + AppleWebApp, + AppLinks, + AppLinksAndroid, + AppLinksApple, + AppLinksWeb, + AppLinksWindows, + FacebookAdmins, + FacebookAppId, + FormatDetection, + ItunesApp, + ResolvedAppleWebApp, + ResolvedAppLinks, + ResolvedFacebook, + ViewportLayout, +} from '../../../../packages/next/src/lib/metadata/types/extra-types' +import { + AlternateLinkDescriptor, + AlternateURLs, + Languages, +} from '../../../../packages/next/src/lib/metadata/types/alternative-urls-types' +import { Manifest } from '../../../../packages/next/src/lib/metadata/types/manifest-types' +import { + Metadata, + MetadataRoute, + Viewport, +} from '../../../../packages/next/src/lib/metadata/types/metadata-interface' +import { + DeprecatedMetadataFields, + Author, + Robots, + IconDescriptor, + Icons, + Verification, + ResolvedVerification, + ResolvedIcons, + ThemeColorDescriptor, + Videos, +} from '../../../../packages/next/src/lib/metadata/types/metadata-types' +import { + OpenGraph, + ResolvedOpenGraph, +} from '../../../../packages/next/src/lib/metadata/types/opengraph-types' +import { + Twitter, + ResolvedTwitterMetadata, +} from '../../../../packages/next/src/lib/metadata/types/twitter-types' +;({ + en: undefined, +}) satisfies Languages +;({ + title: undefined, + url: '', +}) satisfies AlternateLinkDescriptor +;({ + canonical: undefined, + languages: undefined, + media: undefined, + types: undefined, +}) satisfies AlternateURLs +;({ + ios: undefined, + iphone: undefined, + ipad: undefined, + android: undefined, + windows_phone: undefined, + windows: undefined, + windows_universal: undefined, + web: undefined, +}) satisfies AppLinks +;({ + ios: undefined, + iphone: undefined, + ipad: undefined, + android: undefined, + windows_phone: undefined, + windows: undefined, + windows_universal: undefined, + web: undefined, +}) satisfies ResolvedAppLinks +;({ + url: '', + app_store_id: undefined, + app_name: undefined, +}) satisfies AppLinksApple +;({ + package: '', + url: undefined, + class: undefined, + app_name: undefined, +}) satisfies AppLinksAndroid +;({ + url: '', + app_id: undefined, + app_name: undefined, +}) satisfies AppLinksWindows +;({ + url: '', + should_fallback: undefined, +}) satisfies AppLinksWeb +;({ + appId: '', + appArgument: undefined, +}) satisfies ItunesApp +;({ + width: undefined, + height: undefined, + initialScale: undefined, + minimumScale: undefined, + maximumScale: undefined, + userScalable: undefined, + viewportFit: undefined, + interactiveWidget: undefined, +}) satisfies ViewportLayout +;({ + capable: undefined, + title: undefined, + startupImage: undefined, + statusBarStyle: undefined, +}) satisfies AppleWebApp +;({ + url: '', + media: undefined, +}) satisfies AppleImageDescriptor +;({ + capable: false, + title: undefined, + startupImage: undefined, + statusBarStyle: undefined, +}) satisfies ResolvedAppleWebApp +;({ + appId: '', + admins: undefined, +}) satisfies FacebookAppId +;({ + appId: undefined, + admins: '', +}) satisfies FacebookAdmins +;({ + appId: undefined, + admins: undefined, +}) satisfies ResolvedFacebook +;({ + telephone: undefined, + date: undefined, + address: undefined, + email: undefined, + url: undefined, +}) satisfies FormatDetection +;({ + background_color: undefined, + categories: undefined, + description: undefined, + dir: undefined, + display: undefined, + display_override: undefined, + file_handlers: undefined, + icons: undefined, + id: undefined, + lang: undefined, + launch_handler: undefined, + name: undefined, + orientation: undefined, + prefer_related_applications: undefined, + protocol_handlers: undefined, + related_applications: undefined, + scope: undefined, + screenshots: undefined, + share_target: undefined, + short_name: undefined, + shortcuts: undefined, + start_url: undefined, + theme_color: undefined, +}) satisfies Manifest +;({ + related_applications: [ + { + platform: '', + url: '', + id: undefined, + }, + ], + screenshots: [ + { + form_factor: undefined, + label: undefined, + platform: undefined, + src: '', + type: undefined, + sizes: undefined, + }, + ], + share_target: { + action: '', + method: undefined, + enctype: undefined, + params: { + title: undefined, + text: undefined, + url: undefined, + files: undefined, + }, + }, + shortcuts: [ + { + name: '', + short_name: undefined, + description: undefined, + url: '', + icons: undefined, + }, + ], +}) satisfies Manifest +;({ + related_applications: [ + { + platform: '', + url: '', + id: undefined, + }, + ], + screenshots: [ + { + form_factor: undefined, + label: undefined, + platform: undefined, + src: '', + type: undefined, + sizes: undefined, + }, + ], + share_target: { + action: '', + method: undefined, + enctype: undefined, + params: { + title: undefined, + text: undefined, + url: undefined, + files: undefined, + }, + }, + shortcuts: [ + { + name: '', + short_name: undefined, + description: undefined, + url: '', + icons: undefined, + }, + ], +}) satisfies Manifest +;({ + icons: [ + { + src: '', + type: undefined, + sizes: undefined, + purpose: undefined, + }, + ], +}) satisfies Manifest +;({ + metadataBase: undefined, + title: undefined, + description: undefined, + applicationName: undefined, + authors: undefined, + generator: undefined, + keywords: undefined, + referrer: undefined, + themeColor: undefined, + colorScheme: undefined, + viewport: undefined, + creator: undefined, + publisher: undefined, + robots: undefined, + alternates: undefined, + icons: undefined, + manifest: undefined, + openGraph: undefined, + twitter: undefined, + facebook: undefined, + verification: undefined, + appleWebApp: undefined, + formatDetection: undefined, + itunes: undefined, + abstract: undefined, + appLinks: undefined, + archives: undefined, + assets: undefined, + bookmarks: undefined, + category: undefined, + classification: undefined, + other: undefined, +}) satisfies Metadata +;({ + rules: { + userAgent: undefined, + allow: undefined, + disallow: undefined, + crawlDelay: undefined, + }, + sitemap: undefined, + host: undefined, +}) satisfies MetadataRoute.Robots +;({ + url: '', + lastModified: undefined, + changeFrequency: undefined, + priority: undefined, + alternates: undefined, + images: undefined, + videos: undefined, +}) satisfies MetadataRoute.Sitemap[number] +;({ + url: '', + alternates: { + languages: undefined, + }, +}) satisfies MetadataRoute.Sitemap[number] +;({ + themeColor: undefined, + colorScheme: undefined, +}) satisfies Viewport +;({ + 'apple-touch-fullscreen': undefined, + 'apple-touch-icon-precomposed': undefined, +}) satisfies DeprecatedMetadataFields +;({ + url: undefined, + name: undefined, +}) satisfies Author +;({ + googleBot: undefined, + + index: undefined, + follow: undefined, + + noindex: undefined, + nofollow: undefined, + + noarchive: undefined, + nosnippet: undefined, + noimageindex: undefined, + nocache: undefined, + notranslate: undefined, + indexifembedded: undefined, + nositelinkssearchbox: undefined, + unavailable_after: undefined, + 'max-video-preview': undefined, + 'max-image-preview': undefined, + 'max-snippet': undefined, +}) satisfies Robots +;({ + url: '', + type: undefined, + sizes: undefined, + color: undefined, + rel: undefined, + media: undefined, + fetchPriority: undefined, +}) satisfies IconDescriptor +;({ + icon: undefined, + shortcut: undefined, + apple: undefined, + other: undefined, +}) satisfies Icons +;({ + google: undefined, + yahoo: undefined, + yandex: undefined, + me: undefined, + other: undefined, +}) satisfies Verification +;({ + google: undefined, + yahoo: undefined, + yandex: undefined, + me: undefined, + other: undefined, +}) satisfies ResolvedVerification +;({ + icon: [], + apple: [], + shortcut: undefined, + other: undefined, +}) satisfies ResolvedIcons +;({ + color: '', + media: undefined, +}) satisfies ThemeColorDescriptor +;({ + title: '', + thumbnail_loc: '', + description: '', + content_loc: undefined, + player_loc: undefined, + duration: undefined, + expiration_date: undefined, + rating: undefined, + view_count: undefined, + publication_date: undefined, + family_friendly: undefined, + restriction: undefined, + platform: undefined, + requires_subscription: undefined, + uploader: undefined, + live: undefined, + tag: undefined, +}) satisfies Videos +;({ + title: '', + thumbnail_loc: '', + description: '', + uploader: { + info: undefined, + content: undefined, + }, +}) satisfies Videos +;({ + images: { + url: '', + secureUrl: undefined, + alt: undefined, + type: undefined, + width: undefined, + height: undefined, + }, + audio: { + url: '', + secureUrl: undefined, + type: undefined, + }, + videos: { + url: '', + secureUrl: undefined, + type: undefined, + width: undefined, + height: undefined, + }, +}) satisfies OpenGraph +;({ + determiner: undefined, + title: undefined, + description: undefined, + emails: undefined, + phoneNumbers: undefined, + faxNumbers: undefined, + siteName: undefined, + locale: undefined, + alternateLocale: undefined, + images: undefined, + audio: undefined, + videos: undefined, + url: undefined, + countryName: undefined, + ttl: undefined, +}) satisfies OpenGraph +;({ + type: 'article', + publishedTime: undefined, + modifiedTime: undefined, + expirationTime: undefined, + authors: undefined, + section: undefined, + tags: undefined, +}) satisfies OpenGraph +;({ + type: 'book', + isbn: undefined, + releaseDate: undefined, + authors: undefined, + tags: undefined, +}) satisfies OpenGraph +;({ + type: 'music.song', + duration: undefined, + albums: undefined, + musicians: undefined, +}) satisfies OpenGraph +;({ + type: 'music.song', + albums: { + url: '', + disc: undefined, + track: undefined, + }, +}) satisfies OpenGraph +;({ + type: 'music.album', + songs: undefined, + musicians: undefined, + releaseDate: undefined, +}) satisfies OpenGraph +;({ + type: 'music.album', + songs: { + url: '', + disc: undefined, + track: undefined, + }, +}) satisfies OpenGraph +;({ + type: 'music.playlist', + songs: undefined, + creators: undefined, +}) satisfies OpenGraph +;({ + type: 'music.radio_station', + creators: undefined, +}) satisfies OpenGraph +;({ + type: 'video.movie', + actors: undefined, + directors: undefined, + writers: undefined, + duration: undefined, + releaseDate: undefined, + tags: undefined, +}) satisfies OpenGraph +;({ + type: 'video.movie', + actors: { + url: '', + role: undefined, + }, +}) satisfies OpenGraph +;({ + type: 'video.episode', + actors: undefined, + directors: undefined, + writers: undefined, + duration: undefined, + releaseDate: undefined, + tags: undefined, + series: undefined, +}) satisfies OpenGraph +;({ + determiner: undefined, + title: { absolute: '', template: '' }, + description: undefined, + emails: undefined, + phoneNumbers: undefined, + faxNumbers: undefined, + siteName: undefined, + locale: undefined, + alternateLocale: undefined, + images: undefined, + audio: undefined, + videos: undefined, + url: null, + countryName: undefined, + ttl: undefined, +}) satisfies ResolvedOpenGraph +;({ + type: 'article', + title: { absolute: '', template: '' }, + url: null, + publishedTime: undefined, + modifiedTime: undefined, + expirationTime: undefined, + authors: undefined, + section: undefined, + tags: undefined, +}) satisfies ResolvedOpenGraph +;({ + type: 'book', + title: { absolute: '', template: '' }, + url: null, + isbn: undefined, + releaseDate: undefined, + authors: undefined, + tags: undefined, +}) satisfies ResolvedOpenGraph +;({ + type: 'music.song', + title: { absolute: '', template: '' }, + url: null, + duration: undefined, + albums: undefined, + musicians: undefined, +}) satisfies ResolvedOpenGraph +;({ + type: 'music.song', + title: { absolute: '', template: '' }, + url: null, + albums: [ + { + url: '', + disc: undefined, + track: undefined, + }, + ], +}) satisfies ResolvedOpenGraph +;({ + type: 'music.album', + title: { absolute: '', template: '' }, + url: null, + songs: undefined, + musicians: undefined, + releaseDate: undefined, +}) satisfies ResolvedOpenGraph +;({ + type: 'music.album', + title: { absolute: '', template: '' }, + url: null, + songs: [ + { + url: '', + disc: undefined, + track: undefined, + }, + ], +}) satisfies ResolvedOpenGraph +;({ + type: 'music.playlist', + title: { absolute: '', template: '' }, + url: null, + songs: undefined, + creators: undefined, +}) satisfies ResolvedOpenGraph +;({ + type: 'music.radio_station', + title: { absolute: '', template: '' }, + url: null, + creators: undefined, +}) satisfies ResolvedOpenGraph +;({ + type: 'video.movie', + title: { absolute: '', template: '' }, + url: null, + actors: undefined, + directors: undefined, + writers: undefined, + duration: undefined, + releaseDate: undefined, + tags: undefined, +}) satisfies ResolvedOpenGraph +;({ + type: 'video.movie', + title: { absolute: '', template: '' }, + url: null, + actors: [ + { + url: '', + role: undefined, + }, + ], +}) satisfies ResolvedOpenGraph +;({ + type: 'video.episode', + title: { absolute: '', template: '' }, + url: null, + actors: undefined, + directors: undefined, + writers: undefined, + duration: undefined, + releaseDate: undefined, + tags: undefined, + series: undefined, +}) satisfies ResolvedOpenGraph +;({ + site: undefined, + siteId: undefined, + creator: undefined, + creatorId: undefined, + description: undefined, + title: undefined, + images: undefined, +}) satisfies Twitter +;({ + images: { + url: '', + alt: undefined, + secureUrl: undefined, + type: undefined, + width: undefined, + height: undefined, + }, +}) satisfies Twitter +;({ + card: 'app', + app: { + id: { + iphone: undefined, + ipad: undefined, + googleplay: undefined, + }, + url: undefined, + name: undefined, + }, +}) satisfies Twitter +;({ + card: 'app', + app: { + id: {}, + url: { + iphone: undefined, + ipad: undefined, + googleplay: undefined, + }, + }, +}) satisfies Twitter +;({ + card: 'summary', + site: null, + siteId: null, + creator: null, + creatorId: null, + description: null, + title: { absolute: '', template: '' }, + images: undefined, +}) satisfies ResolvedTwitterMetadata +;({ + card: 'summary', + site: null, + siteId: null, + creator: null, + creatorId: null, + description: null, + title: { absolute: '', template: '' }, + images: [ + { + url: '', + alt: undefined, + secureUrl: undefined, + type: undefined, + width: undefined, + height: undefined, + }, + ], +}) satisfies ResolvedTwitterMetadata From 81802ac5c06cd5b441a7ffbdbc5e3b954a50278d Mon Sep 17 00:00:00 2001 From: Boaris Date: Wed, 20 Nov 2024 01:36:23 +0200 Subject: [PATCH 4/4] Rethinking typecheck objects --- .../typescript-basic/typechecking/metadata.ts | 737 ------------------ .../typechecking/metadata/manifest.ts | 76 ++ .../typechecking/metadata/metadata.ts | 507 ++++++++++++ .../typechecking/metadata/robots.ts | 14 + .../typechecking/metadata/sitemap.ts | 59 ++ .../typechecking/metadata/viewport.ts | 22 + 6 files changed, 678 insertions(+), 737 deletions(-) delete mode 100644 test/production/typescript-basic/typechecking/metadata.ts create mode 100644 test/production/typescript-basic/typechecking/metadata/manifest.ts create mode 100644 test/production/typescript-basic/typechecking/metadata/metadata.ts create mode 100644 test/production/typescript-basic/typechecking/metadata/robots.ts create mode 100644 test/production/typescript-basic/typechecking/metadata/sitemap.ts create mode 100644 test/production/typescript-basic/typechecking/metadata/viewport.ts diff --git a/test/production/typescript-basic/typechecking/metadata.ts b/test/production/typescript-basic/typechecking/metadata.ts deleted file mode 100644 index 98e39c235d687..0000000000000 --- a/test/production/typescript-basic/typechecking/metadata.ts +++ /dev/null @@ -1,737 +0,0 @@ -// noinspection BadExpressionStatementJS,ES6PreferShortImport - -import { - AppleImageDescriptor, - AppleWebApp, - AppLinks, - AppLinksAndroid, - AppLinksApple, - AppLinksWeb, - AppLinksWindows, - FacebookAdmins, - FacebookAppId, - FormatDetection, - ItunesApp, - ResolvedAppleWebApp, - ResolvedAppLinks, - ResolvedFacebook, - ViewportLayout, -} from '../../../../packages/next/src/lib/metadata/types/extra-types' -import { - AlternateLinkDescriptor, - AlternateURLs, - Languages, -} from '../../../../packages/next/src/lib/metadata/types/alternative-urls-types' -import { Manifest } from '../../../../packages/next/src/lib/metadata/types/manifest-types' -import { - Metadata, - MetadataRoute, - Viewport, -} from '../../../../packages/next/src/lib/metadata/types/metadata-interface' -import { - DeprecatedMetadataFields, - Author, - Robots, - IconDescriptor, - Icons, - Verification, - ResolvedVerification, - ResolvedIcons, - ThemeColorDescriptor, - Videos, -} from '../../../../packages/next/src/lib/metadata/types/metadata-types' -import { - OpenGraph, - ResolvedOpenGraph, -} from '../../../../packages/next/src/lib/metadata/types/opengraph-types' -import { - Twitter, - ResolvedTwitterMetadata, -} from '../../../../packages/next/src/lib/metadata/types/twitter-types' -;({ - en: undefined, -}) satisfies Languages -;({ - title: undefined, - url: '', -}) satisfies AlternateLinkDescriptor -;({ - canonical: undefined, - languages: undefined, - media: undefined, - types: undefined, -}) satisfies AlternateURLs -;({ - ios: undefined, - iphone: undefined, - ipad: undefined, - android: undefined, - windows_phone: undefined, - windows: undefined, - windows_universal: undefined, - web: undefined, -}) satisfies AppLinks -;({ - ios: undefined, - iphone: undefined, - ipad: undefined, - android: undefined, - windows_phone: undefined, - windows: undefined, - windows_universal: undefined, - web: undefined, -}) satisfies ResolvedAppLinks -;({ - url: '', - app_store_id: undefined, - app_name: undefined, -}) satisfies AppLinksApple -;({ - package: '', - url: undefined, - class: undefined, - app_name: undefined, -}) satisfies AppLinksAndroid -;({ - url: '', - app_id: undefined, - app_name: undefined, -}) satisfies AppLinksWindows -;({ - url: '', - should_fallback: undefined, -}) satisfies AppLinksWeb -;({ - appId: '', - appArgument: undefined, -}) satisfies ItunesApp -;({ - width: undefined, - height: undefined, - initialScale: undefined, - minimumScale: undefined, - maximumScale: undefined, - userScalable: undefined, - viewportFit: undefined, - interactiveWidget: undefined, -}) satisfies ViewportLayout -;({ - capable: undefined, - title: undefined, - startupImage: undefined, - statusBarStyle: undefined, -}) satisfies AppleWebApp -;({ - url: '', - media: undefined, -}) satisfies AppleImageDescriptor -;({ - capable: false, - title: undefined, - startupImage: undefined, - statusBarStyle: undefined, -}) satisfies ResolvedAppleWebApp -;({ - appId: '', - admins: undefined, -}) satisfies FacebookAppId -;({ - appId: undefined, - admins: '', -}) satisfies FacebookAdmins -;({ - appId: undefined, - admins: undefined, -}) satisfies ResolvedFacebook -;({ - telephone: undefined, - date: undefined, - address: undefined, - email: undefined, - url: undefined, -}) satisfies FormatDetection -;({ - background_color: undefined, - categories: undefined, - description: undefined, - dir: undefined, - display: undefined, - display_override: undefined, - file_handlers: undefined, - icons: undefined, - id: undefined, - lang: undefined, - launch_handler: undefined, - name: undefined, - orientation: undefined, - prefer_related_applications: undefined, - protocol_handlers: undefined, - related_applications: undefined, - scope: undefined, - screenshots: undefined, - share_target: undefined, - short_name: undefined, - shortcuts: undefined, - start_url: undefined, - theme_color: undefined, -}) satisfies Manifest -;({ - related_applications: [ - { - platform: '', - url: '', - id: undefined, - }, - ], - screenshots: [ - { - form_factor: undefined, - label: undefined, - platform: undefined, - src: '', - type: undefined, - sizes: undefined, - }, - ], - share_target: { - action: '', - method: undefined, - enctype: undefined, - params: { - title: undefined, - text: undefined, - url: undefined, - files: undefined, - }, - }, - shortcuts: [ - { - name: '', - short_name: undefined, - description: undefined, - url: '', - icons: undefined, - }, - ], -}) satisfies Manifest -;({ - related_applications: [ - { - platform: '', - url: '', - id: undefined, - }, - ], - screenshots: [ - { - form_factor: undefined, - label: undefined, - platform: undefined, - src: '', - type: undefined, - sizes: undefined, - }, - ], - share_target: { - action: '', - method: undefined, - enctype: undefined, - params: { - title: undefined, - text: undefined, - url: undefined, - files: undefined, - }, - }, - shortcuts: [ - { - name: '', - short_name: undefined, - description: undefined, - url: '', - icons: undefined, - }, - ], -}) satisfies Manifest -;({ - icons: [ - { - src: '', - type: undefined, - sizes: undefined, - purpose: undefined, - }, - ], -}) satisfies Manifest -;({ - metadataBase: undefined, - title: undefined, - description: undefined, - applicationName: undefined, - authors: undefined, - generator: undefined, - keywords: undefined, - referrer: undefined, - themeColor: undefined, - colorScheme: undefined, - viewport: undefined, - creator: undefined, - publisher: undefined, - robots: undefined, - alternates: undefined, - icons: undefined, - manifest: undefined, - openGraph: undefined, - twitter: undefined, - facebook: undefined, - verification: undefined, - appleWebApp: undefined, - formatDetection: undefined, - itunes: undefined, - abstract: undefined, - appLinks: undefined, - archives: undefined, - assets: undefined, - bookmarks: undefined, - category: undefined, - classification: undefined, - other: undefined, -}) satisfies Metadata -;({ - rules: { - userAgent: undefined, - allow: undefined, - disallow: undefined, - crawlDelay: undefined, - }, - sitemap: undefined, - host: undefined, -}) satisfies MetadataRoute.Robots -;({ - url: '', - lastModified: undefined, - changeFrequency: undefined, - priority: undefined, - alternates: undefined, - images: undefined, - videos: undefined, -}) satisfies MetadataRoute.Sitemap[number] -;({ - url: '', - alternates: { - languages: undefined, - }, -}) satisfies MetadataRoute.Sitemap[number] -;({ - themeColor: undefined, - colorScheme: undefined, -}) satisfies Viewport -;({ - 'apple-touch-fullscreen': undefined, - 'apple-touch-icon-precomposed': undefined, -}) satisfies DeprecatedMetadataFields -;({ - url: undefined, - name: undefined, -}) satisfies Author -;({ - googleBot: undefined, - - index: undefined, - follow: undefined, - - noindex: undefined, - nofollow: undefined, - - noarchive: undefined, - nosnippet: undefined, - noimageindex: undefined, - nocache: undefined, - notranslate: undefined, - indexifembedded: undefined, - nositelinkssearchbox: undefined, - unavailable_after: undefined, - 'max-video-preview': undefined, - 'max-image-preview': undefined, - 'max-snippet': undefined, -}) satisfies Robots -;({ - url: '', - type: undefined, - sizes: undefined, - color: undefined, - rel: undefined, - media: undefined, - fetchPriority: undefined, -}) satisfies IconDescriptor -;({ - icon: undefined, - shortcut: undefined, - apple: undefined, - other: undefined, -}) satisfies Icons -;({ - google: undefined, - yahoo: undefined, - yandex: undefined, - me: undefined, - other: undefined, -}) satisfies Verification -;({ - google: undefined, - yahoo: undefined, - yandex: undefined, - me: undefined, - other: undefined, -}) satisfies ResolvedVerification -;({ - icon: [], - apple: [], - shortcut: undefined, - other: undefined, -}) satisfies ResolvedIcons -;({ - color: '', - media: undefined, -}) satisfies ThemeColorDescriptor -;({ - title: '', - thumbnail_loc: '', - description: '', - content_loc: undefined, - player_loc: undefined, - duration: undefined, - expiration_date: undefined, - rating: undefined, - view_count: undefined, - publication_date: undefined, - family_friendly: undefined, - restriction: undefined, - platform: undefined, - requires_subscription: undefined, - uploader: undefined, - live: undefined, - tag: undefined, -}) satisfies Videos -;({ - title: '', - thumbnail_loc: '', - description: '', - uploader: { - info: undefined, - content: undefined, - }, -}) satisfies Videos -;({ - images: { - url: '', - secureUrl: undefined, - alt: undefined, - type: undefined, - width: undefined, - height: undefined, - }, - audio: { - url: '', - secureUrl: undefined, - type: undefined, - }, - videos: { - url: '', - secureUrl: undefined, - type: undefined, - width: undefined, - height: undefined, - }, -}) satisfies OpenGraph -;({ - determiner: undefined, - title: undefined, - description: undefined, - emails: undefined, - phoneNumbers: undefined, - faxNumbers: undefined, - siteName: undefined, - locale: undefined, - alternateLocale: undefined, - images: undefined, - audio: undefined, - videos: undefined, - url: undefined, - countryName: undefined, - ttl: undefined, -}) satisfies OpenGraph -;({ - type: 'article', - publishedTime: undefined, - modifiedTime: undefined, - expirationTime: undefined, - authors: undefined, - section: undefined, - tags: undefined, -}) satisfies OpenGraph -;({ - type: 'book', - isbn: undefined, - releaseDate: undefined, - authors: undefined, - tags: undefined, -}) satisfies OpenGraph -;({ - type: 'music.song', - duration: undefined, - albums: undefined, - musicians: undefined, -}) satisfies OpenGraph -;({ - type: 'music.song', - albums: { - url: '', - disc: undefined, - track: undefined, - }, -}) satisfies OpenGraph -;({ - type: 'music.album', - songs: undefined, - musicians: undefined, - releaseDate: undefined, -}) satisfies OpenGraph -;({ - type: 'music.album', - songs: { - url: '', - disc: undefined, - track: undefined, - }, -}) satisfies OpenGraph -;({ - type: 'music.playlist', - songs: undefined, - creators: undefined, -}) satisfies OpenGraph -;({ - type: 'music.radio_station', - creators: undefined, -}) satisfies OpenGraph -;({ - type: 'video.movie', - actors: undefined, - directors: undefined, - writers: undefined, - duration: undefined, - releaseDate: undefined, - tags: undefined, -}) satisfies OpenGraph -;({ - type: 'video.movie', - actors: { - url: '', - role: undefined, - }, -}) satisfies OpenGraph -;({ - type: 'video.episode', - actors: undefined, - directors: undefined, - writers: undefined, - duration: undefined, - releaseDate: undefined, - tags: undefined, - series: undefined, -}) satisfies OpenGraph -;({ - determiner: undefined, - title: { absolute: '', template: '' }, - description: undefined, - emails: undefined, - phoneNumbers: undefined, - faxNumbers: undefined, - siteName: undefined, - locale: undefined, - alternateLocale: undefined, - images: undefined, - audio: undefined, - videos: undefined, - url: null, - countryName: undefined, - ttl: undefined, -}) satisfies ResolvedOpenGraph -;({ - type: 'article', - title: { absolute: '', template: '' }, - url: null, - publishedTime: undefined, - modifiedTime: undefined, - expirationTime: undefined, - authors: undefined, - section: undefined, - tags: undefined, -}) satisfies ResolvedOpenGraph -;({ - type: 'book', - title: { absolute: '', template: '' }, - url: null, - isbn: undefined, - releaseDate: undefined, - authors: undefined, - tags: undefined, -}) satisfies ResolvedOpenGraph -;({ - type: 'music.song', - title: { absolute: '', template: '' }, - url: null, - duration: undefined, - albums: undefined, - musicians: undefined, -}) satisfies ResolvedOpenGraph -;({ - type: 'music.song', - title: { absolute: '', template: '' }, - url: null, - albums: [ - { - url: '', - disc: undefined, - track: undefined, - }, - ], -}) satisfies ResolvedOpenGraph -;({ - type: 'music.album', - title: { absolute: '', template: '' }, - url: null, - songs: undefined, - musicians: undefined, - releaseDate: undefined, -}) satisfies ResolvedOpenGraph -;({ - type: 'music.album', - title: { absolute: '', template: '' }, - url: null, - songs: [ - { - url: '', - disc: undefined, - track: undefined, - }, - ], -}) satisfies ResolvedOpenGraph -;({ - type: 'music.playlist', - title: { absolute: '', template: '' }, - url: null, - songs: undefined, - creators: undefined, -}) satisfies ResolvedOpenGraph -;({ - type: 'music.radio_station', - title: { absolute: '', template: '' }, - url: null, - creators: undefined, -}) satisfies ResolvedOpenGraph -;({ - type: 'video.movie', - title: { absolute: '', template: '' }, - url: null, - actors: undefined, - directors: undefined, - writers: undefined, - duration: undefined, - releaseDate: undefined, - tags: undefined, -}) satisfies ResolvedOpenGraph -;({ - type: 'video.movie', - title: { absolute: '', template: '' }, - url: null, - actors: [ - { - url: '', - role: undefined, - }, - ], -}) satisfies ResolvedOpenGraph -;({ - type: 'video.episode', - title: { absolute: '', template: '' }, - url: null, - actors: undefined, - directors: undefined, - writers: undefined, - duration: undefined, - releaseDate: undefined, - tags: undefined, - series: undefined, -}) satisfies ResolvedOpenGraph -;({ - site: undefined, - siteId: undefined, - creator: undefined, - creatorId: undefined, - description: undefined, - title: undefined, - images: undefined, -}) satisfies Twitter -;({ - images: { - url: '', - alt: undefined, - secureUrl: undefined, - type: undefined, - width: undefined, - height: undefined, - }, -}) satisfies Twitter -;({ - card: 'app', - app: { - id: { - iphone: undefined, - ipad: undefined, - googleplay: undefined, - }, - url: undefined, - name: undefined, - }, -}) satisfies Twitter -;({ - card: 'app', - app: { - id: {}, - url: { - iphone: undefined, - ipad: undefined, - googleplay: undefined, - }, - }, -}) satisfies Twitter -;({ - card: 'summary', - site: null, - siteId: null, - creator: null, - creatorId: null, - description: null, - title: { absolute: '', template: '' }, - images: undefined, -}) satisfies ResolvedTwitterMetadata -;({ - card: 'summary', - site: null, - siteId: null, - creator: null, - creatorId: null, - description: null, - title: { absolute: '', template: '' }, - images: [ - { - url: '', - alt: undefined, - secureUrl: undefined, - type: undefined, - width: undefined, - height: undefined, - }, - ], -}) satisfies ResolvedTwitterMetadata diff --git a/test/production/typescript-basic/typechecking/metadata/manifest.ts b/test/production/typescript-basic/typechecking/metadata/manifest.ts new file mode 100644 index 0000000000000..e1960683636c9 --- /dev/null +++ b/test/production/typescript-basic/typechecking/metadata/manifest.ts @@ -0,0 +1,76 @@ +import type { MetadataRoute } from 'next' +// eslint-disable-next-line @typescript-eslint/no-unused-expressions +;() => { + ;({ + background_color: undefined, + categories: undefined, + description: undefined, + dir: undefined, + display: undefined, + display_override: undefined, + file_handlers: undefined, + icons: undefined, + id: undefined, + lang: undefined, + launch_handler: undefined, + name: undefined, + orientation: undefined, + prefer_related_applications: undefined, + protocol_handlers: undefined, + related_applications: undefined, + scope: undefined, + screenshots: undefined, + share_target: undefined, + short_name: undefined, + shortcuts: undefined, + start_url: undefined, + theme_color: undefined, + }) satisfies MetadataRoute.Manifest + ;({ + icons: [ + { + src: '', + type: undefined, + sizes: undefined, + purpose: undefined, + }, + ], + related_applications: [ + { + platform: '', + url: '', + id: undefined, + }, + ], + screenshots: [ + { + form_factor: undefined, + label: undefined, + platform: undefined, + src: '', + type: undefined, + sizes: undefined, + }, + ], + share_target: { + action: '', + method: undefined, + enctype: undefined, + params: { + title: undefined, + text: undefined, + url: undefined, + files: undefined, + }, + }, + shortcuts: [ + { + name: '', + short_name: undefined, + description: undefined, + url: '', + icons: undefined, + }, + ], + }) satisfies MetadataRoute.Manifest +} diff --git a/test/production/typescript-basic/typechecking/metadata/metadata.ts b/test/production/typescript-basic/typechecking/metadata/metadata.ts new file mode 100644 index 0000000000000..5b1e52f3c0264 --- /dev/null +++ b/test/production/typescript-basic/typechecking/metadata/metadata.ts @@ -0,0 +1,507 @@ +import type { Metadata } from 'next' +import { ResolvedMetadata } from 'next/types' +// eslint-disable-next-line @typescript-eslint/no-unused-expressions +;() => { + ;({ + 'apple-touch-fullscreen': undefined, + 'apple-touch-icon-precomposed': undefined, + metadataBase: undefined, + title: undefined, + description: undefined, + applicationName: undefined, + authors: undefined, + generator: undefined, + keywords: undefined, + referrer: undefined, + themeColor: undefined, + colorScheme: undefined, + viewport: undefined, + creator: undefined, + publisher: undefined, + robots: undefined, + alternates: undefined, + icons: undefined, + manifest: undefined, + openGraph: undefined, + twitter: undefined, + facebook: undefined, + verification: undefined, + appleWebApp: undefined, + formatDetection: undefined, + itunes: undefined, + abstract: undefined, + appLinks: undefined, + archives: undefined, + assets: undefined, + bookmarks: undefined, + category: undefined, + classification: undefined, + other: undefined, + }) satisfies Metadata + ;({ + authors: { + url: undefined, + name: undefined, + }, + themeColor: { + color: '', + media: undefined, + }, + viewport: { + width: undefined, + height: undefined, + initialScale: undefined, + minimumScale: undefined, + maximumScale: undefined, + userScalable: undefined, + viewportFit: undefined, + interactiveWidget: undefined, + }, + robots: { + googleBot: undefined, + + index: undefined, + follow: undefined, + + noindex: undefined, + nofollow: undefined, + + noarchive: undefined, + nosnippet: undefined, + noimageindex: undefined, + nocache: undefined, + notranslate: undefined, + indexifembedded: undefined, + nositelinkssearchbox: undefined, + unavailable_after: undefined, + 'max-video-preview': undefined, + 'max-image-preview': undefined, + 'max-snippet': undefined, + }, + alternates: { + canonical: undefined, + languages: undefined, + media: undefined, + types: undefined, + }, + icons: { + icon: undefined, + shortcut: undefined, + apple: undefined, + other: { + url: '', + type: undefined, + sizes: undefined, + color: undefined, + rel: undefined, + media: undefined, + fetchPriority: undefined, + }, + }, + verification: { + google: undefined, + yahoo: undefined, + yandex: undefined, + me: undefined, + other: undefined, + }, + formatDetection: { + telephone: undefined, + date: undefined, + address: undefined, + email: undefined, + url: undefined, + }, + itunes: { + appId: '', + appArgument: undefined, + }, + }) satisfies Metadata + ;({ + canonical: { + title: undefined, + url: '', + }, + }) satisfies Metadata['alternates'] + ;({ + type: 'website', + determiner: undefined, + title: undefined, + description: undefined, + emails: undefined, + phoneNumbers: undefined, + faxNumbers: undefined, + siteName: undefined, + locale: undefined, + alternateLocale: undefined, + images: undefined, + audio: undefined, + videos: undefined, + url: undefined, + countryName: undefined, + ttl: undefined, + }) satisfies Metadata['openGraph'] + ;({ + images: { + url: '', + secureUrl: undefined, + alt: undefined, + type: undefined, + width: undefined, + height: undefined, + }, + audio: { + url: '', + secureUrl: undefined, + type: undefined, + }, + videos: { + url: '', + secureUrl: undefined, + type: undefined, + width: undefined, + height: undefined, + }, + }) satisfies Metadata['openGraph'] + ;({ + type: 'article', + publishedTime: undefined, + modifiedTime: undefined, + expirationTime: undefined, + authors: undefined, + section: undefined, + tags: undefined, + }) satisfies Metadata['openGraph'] + ;({ + type: 'book', + isbn: undefined, + releaseDate: undefined, + authors: undefined, + tags: undefined, + }) satisfies Metadata['openGraph'] + ;({ + type: 'profile', + firstName: undefined, + lastName: undefined, + username: undefined, + gender: undefined, + }) satisfies Metadata['openGraph'] + ;({ + type: 'music.song', + duration: undefined, + albums: undefined, + musicians: undefined, + }) satisfies Metadata['openGraph'] + ;({ + type: 'music.song', + albums: { + url: '', + disc: undefined, + track: undefined, + }, + }) satisfies Metadata['openGraph'] + ;({ + type: 'music.album', + songs: undefined, + musicians: undefined, + releaseDate: undefined, + }) satisfies Metadata['openGraph'] + ;({ + type: 'music.album', + songs: { + url: '', + disc: undefined, + track: undefined, + }, + }) satisfies Metadata['openGraph'] + ;({ + type: 'music.playlist', + songs: undefined, + creators: undefined, + }) satisfies Metadata['openGraph'] + ;({ + type: 'music.radio_station', + creators: undefined, + }) satisfies Metadata['openGraph'] + ;({ + type: 'video.movie', + actors: undefined, + directors: undefined, + writers: undefined, + duration: undefined, + releaseDate: undefined, + tags: undefined, + }) satisfies Metadata['openGraph'] + ;({ + type: 'video.movie', + actors: { + url: '', + role: undefined, + }, + }) satisfies Metadata['openGraph'] + ;({ + type: 'video.episode', + actors: undefined, + directors: undefined, + writers: undefined, + duration: undefined, + releaseDate: undefined, + tags: undefined, + series: undefined, + }) satisfies Metadata['openGraph'] + ;({ + card: 'app', + site: undefined, + siteId: undefined, + creator: undefined, + creatorId: undefined, + description: undefined, + title: undefined, + images: undefined, + app: { + id: {}, + url: undefined, + name: undefined, + }, + }) satisfies Metadata['twitter'] + ;({ + card: 'app', + images: { + url: '', + alt: undefined, + secureUrl: undefined, + type: undefined, + width: undefined, + height: undefined, + }, + app: { + id: { + iphone: undefined, + ipad: undefined, + googleplay: undefined, + }, + url: { + iphone: undefined, + ipad: undefined, + googleplay: undefined, + }, + }, + }) satisfies Metadata['twitter'] + ;({ + appId: '', + admins: undefined, + }) satisfies Metadata['facebook'] + ;({ + appId: undefined, + admins: '', + }) satisfies Metadata['facebook'] + ;({ + capable: undefined, + title: undefined, + startupImage: undefined, + statusBarStyle: undefined, + }) satisfies Metadata['appleWebApp'] + ;({ + startupImage: { + url: '', + media: undefined, + }, + }) satisfies Metadata['appleWebApp'] + ;({ + ios: undefined, + iphone: undefined, + ipad: undefined, + android: undefined, + windows_phone: undefined, + windows: undefined, + windows_universal: undefined, + web: undefined, + }) satisfies Metadata['appLinks'] + ;({ + ios: { + url: '', + app_store_id: undefined, + app_name: undefined, + }, + android: { + package: '', + url: undefined, + class: undefined, + app_name: undefined, + }, + windows_phone: { + url: '', + app_id: undefined, + app_name: undefined, + }, + web: { + url: '', + should_fallback: undefined, + }, + }) satisfies Metadata['appLinks'] + ;({ + icon: [], + apple: [], + shortcut: undefined, + other: undefined, + }) satisfies ResolvedMetadata['icons'] + ;({ + determiner: undefined, + title: { template: null, absolute: '' }, + description: undefined, + emails: undefined, + phoneNumbers: undefined, + faxNumbers: undefined, + siteName: undefined, + locale: undefined, + alternateLocale: undefined, + images: undefined, + audio: undefined, + videos: undefined, + url: null, + countryName: undefined, + ttl: undefined, + }) satisfies ResolvedMetadata['openGraph'] + ;({ + title: { template: null, absolute: '' }, + url: null, + type: 'article', + publishedTime: undefined, + modifiedTime: undefined, + expirationTime: undefined, + authors: undefined, + section: undefined, + tags: undefined, + }) satisfies ResolvedMetadata['openGraph'] + ;({ + title: { template: null, absolute: '' }, + url: null, + type: 'book', + isbn: undefined, + releaseDate: undefined, + authors: undefined, + tags: undefined, + }) satisfies ResolvedMetadata['openGraph'] + ;({ + title: { template: null, absolute: '' }, + url: null, + type: 'book', + }) satisfies ResolvedMetadata['openGraph'] + ;({ + title: { template: null, absolute: '' }, + url: null, + type: 'profile', + firstName: undefined, + lastName: undefined, + username: undefined, + gender: undefined, + }) satisfies ResolvedMetadata['openGraph'] + ;({ + title: { template: null, absolute: '' }, + url: null, + type: 'music.song', + duration: undefined, + albums: undefined, + musicians: undefined, + }) satisfies ResolvedMetadata['openGraph'] + ;({ + title: { template: null, absolute: '' }, + url: null, + type: 'music.album', + songs: undefined, + musicians: undefined, + releaseDate: undefined, + }) satisfies ResolvedMetadata['openGraph'] + ;({ + title: { template: null, absolute: '' }, + url: null, + type: 'music.playlist', + songs: undefined, + creators: undefined, + }) satisfies ResolvedMetadata['openGraph'] + ;({ + title: { template: null, absolute: '' }, + url: null, + type: 'music.radio_station', + creators: undefined, + }) satisfies ResolvedMetadata['openGraph'] + ;({ + title: { template: null, absolute: '' }, + url: null, + type: 'video.movie', + actors: undefined, + directors: undefined, + writers: undefined, + duration: undefined, + releaseDate: undefined, + tags: undefined, + }) satisfies ResolvedMetadata['openGraph'] + ;({ + title: { template: null, absolute: '' }, + url: null, + type: 'video.episode', + actors: undefined, + directors: undefined, + writers: undefined, + duration: undefined, + releaseDate: undefined, + tags: undefined, + series: undefined, + }) satisfies ResolvedMetadata['openGraph'] + ;({ + card: 'summary', + site: null, + siteId: null, + creator: null, + creatorId: null, + description: null, + title: { template: null, absolute: '' }, + images: undefined, + }) satisfies ResolvedMetadata['twitter'] + ;({ + card: 'summary', + site: null, + siteId: null, + creator: null, + creatorId: null, + description: null, + title: { template: null, absolute: '' }, + images: [ + { + url: '', + alt: undefined, + secureUrl: undefined, + type: undefined, + width: undefined, + height: undefined, + }, + ], + }) satisfies ResolvedMetadata['twitter'] + ;({ + appId: undefined, + admins: undefined, + }) satisfies ResolvedMetadata['facebook'] + ;({ + google: undefined, + yahoo: undefined, + yandex: undefined, + me: undefined, + other: undefined, + }) satisfies ResolvedMetadata['verification'] + ;({ + capable: false, + title: undefined, + startupImage: undefined, + statusBarStyle: undefined, + }) satisfies ResolvedMetadata['appleWebApp'] + ;({ + ios: undefined, + iphone: undefined, + ipad: undefined, + android: undefined, + windows_phone: undefined, + windows: undefined, + windows_universal: undefined, + web: undefined, + }) satisfies ResolvedMetadata['appLinks'] +} diff --git a/test/production/typescript-basic/typechecking/metadata/robots.ts b/test/production/typescript-basic/typechecking/metadata/robots.ts new file mode 100644 index 0000000000000..b0aabe53cf996 --- /dev/null +++ b/test/production/typescript-basic/typechecking/metadata/robots.ts @@ -0,0 +1,14 @@ +import type { MetadataRoute } from 'next' +// eslint-disable-next-line @typescript-eslint/no-unused-expressions +;() => { + ;({ + rules: { + userAgent: undefined, + allow: undefined, + disallow: undefined, + crawlDelay: undefined, + }, + sitemap: undefined, + host: undefined, + }) satisfies MetadataRoute.Robots +} diff --git a/test/production/typescript-basic/typechecking/metadata/sitemap.ts b/test/production/typescript-basic/typechecking/metadata/sitemap.ts new file mode 100644 index 0000000000000..039d086a305b5 --- /dev/null +++ b/test/production/typescript-basic/typechecking/metadata/sitemap.ts @@ -0,0 +1,59 @@ +import type { MetadataRoute } from 'next' +// eslint-disable-next-line @typescript-eslint/no-unused-expressions +;() => { + ;({ + url: '', + lastModified: undefined, + changeFrequency: undefined, + priority: undefined, + alternates: undefined, + images: undefined, + videos: undefined, + }) satisfies MetadataRoute.Sitemap[number] + ;({ + url: '', + alternates: { + languages: undefined, + }, + videos: [ + { + title: '', + thumbnail_loc: '', + description: '', + content_loc: undefined, + player_loc: undefined, + duration: undefined, + expiration_date: undefined, + rating: undefined, + view_count: undefined, + publication_date: undefined, + family_friendly: undefined, + restriction: undefined, + platform: undefined, + requires_subscription: undefined, + uploader: undefined, + live: undefined, + tag: undefined, + }, + ], + }) satisfies MetadataRoute.Sitemap[number] + ;({ + url: '', + alternates: { + languages: { + en: undefined, + }, + }, + videos: [ + { + title: '', + thumbnail_loc: '', + description: '', + uploader: { + info: undefined, + content: undefined, + }, + }, + ], + }) satisfies MetadataRoute.Sitemap[number] +} diff --git a/test/production/typescript-basic/typechecking/metadata/viewport.ts b/test/production/typescript-basic/typechecking/metadata/viewport.ts new file mode 100644 index 0000000000000..c159812c01954 --- /dev/null +++ b/test/production/typescript-basic/typechecking/metadata/viewport.ts @@ -0,0 +1,22 @@ +import type { Viewport } from 'next' +// eslint-disable-next-line @typescript-eslint/no-unused-expressions +;() => { + ;({ + width: undefined, + height: undefined, + initialScale: undefined, + minimumScale: undefined, + maximumScale: undefined, + userScalable: undefined, + viewportFit: undefined, + interactiveWidget: undefined, + themeColor: undefined, + colorScheme: undefined, + }) satisfies Viewport + ;({ + themeColor: { + color: '', + media: undefined, + }, + }) satisfies Viewport +}