We have a structure that is like the following:
export type LinkRestSource = {
model: string;
rel?: string;
title?: string;
} | {
model?: str
A simpler version of the solution by jcalz:
type AtLeastOne
so the whole implementation becomes
type FullLinkRestSource = {
model: string;
rel: string;
title: string;
}
type AtLeastOne = { [K in keyof T]: Pick }[keyof T]
type LinkRestSource = AtLeastOne
const okay0: LinkRestSource = { model: 'a', rel: 'b', title: 'c' }
const okay1: LinkRestSource = { model: 'a', rel: 'b' }
const okay2: LinkRestSource = { model: 'a' }
const okay3: LinkRestSource = { rel: 'b' }
const okay4: LinkRestSource = { title: 'c' }
const error0: LinkRestSource = {} // missing property
const error1: LinkRestSource = { model: 'a', titel: 'c' } // excess property on string literal
and here's the TS playground link to try it