From 997116a343a17f8c65174c3085230820fc379233 Mon Sep 17 00:00:00 2001 From: tomeelog Date: Mon, 20 Apr 2026 16:06:52 +0100 Subject: [PATCH] fix(image): inline ImageFit and ImagePosition types to avoid csstype leak (TS2742) Using CSSProperties['objectFit'] and CSSProperties['objectPosition'] caused the generated d.ts to reference csstype.Property.ObjectFit / ObjectPosition, which triggered TS2742 in consumer projects that do not have csstype as a direct dependency. Replace both with self-contained types: - ImageFit: explicit union of valid CSS object-fit keyword values - ImagePosition: string (object-position accepts arbitrary CSS length/keyword values) Fixes #13818 --- packages/vant/src/image/test/index.spec.ts | 23 ++++++++++++++++++++++ packages/vant/src/image/types.ts | 13 ++++++++---- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/packages/vant/src/image/test/index.spec.ts b/packages/vant/src/image/test/index.spec.ts index 2e021f37ee5..b55570ab01c 100644 --- a/packages/vant/src/image/test/index.spec.ts +++ b/packages/vant/src/image/test/index.spec.ts @@ -2,6 +2,7 @@ import 'rstest-canvas-mock'; import { mount } from '../../../test'; import { Lazyload } from '../../lazyload'; import VanImage from '..'; +import type { ImageFit, ImagePosition } from '../types'; const IMAGE_URL = 'https://img.com'; @@ -244,3 +245,25 @@ test('should render default slot correctly', () => { // }, // }); // }); + +// Regression test for https://github.com/youzan/vant/issues/13818 +// ImageFit and ImagePosition must be self-contained types that do not +// reference csstype, so that consumers generating d.ts files do not +// encounter TS2742 ("cannot be named without a reference to …csstype"). +test('ImageFit only allows valid CSS object-fit keywords', () => { + const validFits: ImageFit[] = ['contain', 'cover', 'fill', 'none', 'scale-down']; + validFits.forEach((fit) => { + const wrapper = mount(VanImage, { + props: { src: 'https://img.com', fit }, + }); + expect(wrapper.find('img').attributes('style')).toContain(`object-fit: ${fit}`); + }); +}); + +test('ImagePosition accepts a string value', () => { + const position: ImagePosition = 'center top'; + const wrapper = mount(VanImage, { + props: { src: 'https://img.com', position }, + }); + expect(wrapper.find('img').attributes('style')).toContain('object-position: center top'); +}); diff --git a/packages/vant/src/image/types.ts b/packages/vant/src/image/types.ts index aafdf4f0deb..ddef2283886 100644 --- a/packages/vant/src/image/types.ts +++ b/packages/vant/src/image/types.ts @@ -1,8 +1,13 @@ -import type { CSSProperties } from 'vue'; +// Use explicit union types instead of CSSProperties lookups to avoid +// csstype leaking into consumers' generated d.ts files (TS2742). +export type ImageFit = + | 'contain' + | 'cover' + | 'fill' + | 'none' + | 'scale-down'; -export type ImageFit = CSSProperties['objectFit']; - -export type ImagePosition = CSSProperties['objectPosition']; +export type ImagePosition = string; export type ImageThemeVars = { imagePlaceholderTextColor?: string;