定义另一个属性时需要一个属性(有区别的联合)

rss*_*ncs 5 typescript

我想编写一种类型,它允许创建具有一些始终需要的核心属性和一个可选属性的对象,该属性imageUrl在定义为字符串时imageAltText也需要作为字符串,

{
 id: "test",
 imageUrl: "test",
 imageAltText: "test"
}
Run Code Online (Sandbox Code Playgroud)

我还希望它能够工作,以便何时imageUrl未定义我不希望imageAltText被定义。

{
 id: "test"
}
Run Code Online (Sandbox Code Playgroud)

我已将类型定义如下,

(
  {
    /** image url for the banner of the card. Will display a blue background without an image */
    imageUrl?: undefined;
  } 
| 
  {
    /** image url for the banner of the card. Will display a blue background without an image */
    imageUrl: string;
      /** alternative text for the banner image */
    imageAltText: string;
  }
)

However, by making `imageUrl` optional `?` typescript allows me to write `imageAltText` even when `imageUrl` is undefined. 
Run Code Online (Sandbox Code Playgroud)

cap*_*ian 3

在这里你有:


type RequiredParams<T = {}> = {
    id: string
} & T

type UnionParams =
    | RequiredParams<{ imageUrl: string; imageAltText: string; }>
    | RequiredParams

type UnionKeys<T> = T extends T ? keyof T : never;
type StrictUnionHelper<T, TAll> =
    T extends any
    ? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, never>> : never;

type StrictUnion<T> = StrictUnionHelper<T, T>

type Result = StrictUnion<UnionParams>

const a: Result = { id: 'sdf' }; // ok
const b: Result = { id: 'sdf', imageUrl: 'sdf', imageAltText: 'sdf' } // ok
const c: Result = { id: 'sdf', imageUrl: 'sdf' } // error
const d: Result = { id: 'sdf', imageAltText: 'sdf' } // error
Run Code Online (Sandbox Code Playgroud)

所有功劳归@Titian Cernicova-Dragomir