diff --git a/packages/astro/client.d.ts b/packages/astro/client.d.ts index 5d1cf745b..90f06c72d 100644 --- a/packages/astro/client.d.ts +++ b/packages/astro/client.d.ts @@ -57,17 +57,15 @@ declare module 'astro:assets' { Image: typeof import('./components/Image.astro').default; }; - type WithRequired = T & { [P in K]-?: T[P] }; - type Simplify = { [KeyType in keyof T]: T[KeyType] } & {}; - type ImgAttributes = WithRequired< + type ImgAttributes = import('./dist/type-utils.js').WithRequired< Omit, 'src' | 'width' | 'height'>, 'alt' >; - export type LocalImageProps = Simplify< + export type LocalImageProps = import('./dist/type-utils.js').Simplify< import('./dist/assets/types.js').LocalImageProps >; - export type RemoteImageProps = Simplify< + export type RemoteImageProps = import('./dist/type-utils.js').Simplify< import('./dist/assets/types.js').RemoteImageProps >; export const { getImage, getConfiguredImageService, imageConfig, Image }: AstroAssets; diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts index 73b652db6..e99077d35 100644 --- a/packages/astro/src/@types/astro.ts +++ b/packages/astro/src/@types/astro.ts @@ -22,6 +22,7 @@ import type { AstroCookies } from '../core/cookies'; import type { ResponseWithEncoding } from '../core/endpoint/index.js'; import type { AstroIntegrationLogger, Logger, LoggerLevel } from '../core/logger/core'; import type { AstroComponentFactory, AstroComponentInstance } from '../runtime/server'; +import type { OmitIndexSignature, Simplify } from '../type-utils'; import type { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from './../core/constants.js'; export { type AstroIntegrationLogger }; @@ -1725,14 +1726,6 @@ export interface Page { }; } -type OmitIndexSignature = { - // eslint-disable-next-line @typescript-eslint/ban-types - [KeyType in keyof ObjectType as {} extends Record - ? never - : KeyType]: ObjectType[KeyType]; -}; -// eslint-disable-next-line @typescript-eslint/ban-types -type Simplify = { [KeyType in keyof T]: T[KeyType] } & {}; export type PaginateFunction = < PaginateData, AdditionalPaginateProps extends Props, diff --git a/packages/astro/src/assets/types.ts b/packages/astro/src/assets/types.ts index ae74fc692..0bf740d57 100644 --- a/packages/astro/src/assets/types.ts +++ b/packages/astro/src/assets/types.ts @@ -1,4 +1,5 @@ /* eslint-disable @typescript-eslint/ban-types */ +import type { WithRequired } from '../type-utils.js'; import type { VALID_INPUT_FORMATS, VALID_OUTPUT_FORMATS } from './consts.js'; import type { ImageService } from './services/service.js'; @@ -50,7 +51,6 @@ export interface GetImageResult { attributes: Record; } -type WithRequired = T & { [P in K]-?: T[P] }; type ImageSharedProps = T & { /** * Width of the image, the value of this property will be used to assign the `width` property on the final `img` element. diff --git a/packages/astro/src/runtime/server/serialize.ts b/packages/astro/src/runtime/server/serialize.ts index 479552260..b52c9e215 100644 --- a/packages/astro/src/runtime/server/serialize.ts +++ b/packages/astro/src/runtime/server/serialize.ts @@ -1,6 +1,5 @@ import type { AstroComponentMetadata } from '../../@types/astro'; - -type ValueOf = T[keyof T]; +import type { ValueOf } from '../../type-utils'; const PROP_TYPE = { Value: 0, diff --git a/packages/astro/src/type-utils.ts b/packages/astro/src/type-utils.ts new file mode 100644 index 000000000..926b0349d --- /dev/null +++ b/packages/astro/src/type-utils.ts @@ -0,0 +1,21 @@ +/* eslint-disable @typescript-eslint/ban-types */ +// Q: Why is this not in @types? +// A: `@types` is for types that are part of the public API. This is just a bunch of utilities we use throughout the codebase. (Mostly by Erika) + +// Merge all the intersection of a type into one type. This is useful for making tooltips better in the editor for complex types +// Ex: The Image component props are a merge of all the properties that can be on an `img` tag and our props, in the editor +// this results in a very opaque type that just says `ImgAttributes & ImageComponentProps`. With this, all the props shows. +export type Simplify = { [KeyType in keyof T]: T[KeyType] } & {}; + +// Mark certain properties of a type as required. Think of it like "This type, with those specific properties required" +export type WithRequired = T & { [P in K]-?: T[P] }; + +// Name is pretty self descriptive, but it removes the index signature of an object +export type OmitIndexSignature = { + [KeyType in keyof ObjectType as {} extends Record + ? never + : KeyType]: ObjectType[KeyType]; +}; + +// Similar to `keyof`, gets the type of all the values of an object +export type ValueOf = T[keyof T];