i can enforce the fix size of array by doing following:

export type ArrayOneOrMore<T> = {
	0: T;
} & Array<T>;
 
export type ArrayTwoOrMore<T> = {
	0: T;
	1: T;
} & Array<T>;
 

another way to write this is like this, but i prefer Array because it’s more intiutive

export type ArrayOneOrMore<T> = {
	0: T;
} & T[];
 
export type ArrayTwoOrMore<T> = {
	0: T;
	1: T;
} & T[];
 

+ or - allows control over the mapped type modifier (? or readonly). -? means must be all present, aka it removes optionality (?

type T = {
    a: string
    b?: string
}
 
 
// Note b is optional
const sameAsT: { [K in keyof T]: string } = {
    a: 'asdf', // a is required
}
 
// Note a became optional
const canBeNotPresent: { [K in keyof T]?: string } = {
}
 
// Note b became required
const mustBePreset: { [K in keyof T]-?: string } = {
    a: 'asdf', 
    b: 'asdf'  // b became required 
}

Required only one:

export type RequireOnlyOne<T, Keys extends keyof T = keyof T> = Pick<
	T,
	Exclude<keyof T, Keys>
> &
	{
		[K in Keys]-?: Required<Pick<T, K>> & Partial<Record<Exclude<Keys, K>, undefined>>;
	}[Keys];
 
 
// example:
interface User {
  name?: string;
  email?: string;
  phone?: string;
}
 
// Must have exactly one of name, email, or phone
type SingleContactMethod = RequireOnlyOne<User, 'name' | 'email' | 'phone'>;
 
// Valid examples:
const valid1: SingleContactMethod = { name: 'John' };
const valid2: SingleContactMethod = { email: 'john@example.com' };
const valid3: SingleContactMethod = { phone: '123-456-7890' };
 
// Invalid examples (will cause type errors):
const invalid1: SingleContactMethod = {}; // No contact method
const invalid2: SingleContactMethod = { name: 'John', email: 'john@example.com' }; // Multiple contact methods

RequiredAtLeastOne:

export type RequireAtLeastOne<T> = {
	[K in keyof T]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<keyof T, K>>>;
}[keyof T];

Omit is for removing specific property from object

interface User {
  id: number;
  name: string;
  email: string;
  age: number;
}
 
// Create a type without 'email' and 'age' properties
type UserWithoutSensitiveInfo = Omit<User, 'email' | 'age'>;
 
// UserWithoutSensitiveInfo now only has 'id' and 'name'
const safeUser: UserWithoutSensitiveInfo = {
  id: 1,
  name: "John"
  // email and age are not allowed
};

Exclude is for removing specific type from union type

// Exclude removes specific types from a union
type NumberOrString = number | string | boolean;
 
// Removes number and boolean from the union
type StringOnly = Exclude<NumberOrString, number | boolean>;
 
// StringOnly is now just 'string'
const value: StringOnly = "hello"; // OK
// const numValue: StringOnly = 42; // Would be a type error