1interface Settings { 2 timeout?: number; 3 onError?(): void; 4} 5 6function getDefaultSettings() { 7 return { timeout: 1000 }; 8} 9interface CtorOnly { 10 new(s: string): { timeout: 1000 } 11} 12 13function doSomething(settings: Settings) { /* ... */ } 14// forgot to call `getDefaultSettings` 15doSomething(getDefaultSettings); 16doSomething(() => ({ timeout: 1000 })); 17doSomething(null as CtorOnly); 18doSomething(12); 19doSomething('completely wrong'); 20doSomething(false); 21 22// this is an oddly popular way of defining settings 23// this example is from services/textChanges.ts 24type ConfigurableStart = { useStart?: boolean } 25type ConfigurableEnd = { useEnd?: boolean } 26type ConfigurableStartEnd = ConfigurableStart & ConfigurableEnd 27interface InsertOptions { 28 prefix?: string 29 suffix?: string 30} 31type ChangeOptions = ConfigurableStartEnd & InsertOptions; 32 33function del(options: ConfigurableStartEnd = {}, 34 error: { error?: number } = {}) { 35 let changes: ChangeOptions[]; 36 changes.push(options); 37 changes.push(error); 38} 39 40class K { 41 constructor(s: string) { } 42} 43// Ctor isn't a weak type because it has a construct signature 44interface Ctor { 45 new (s: string): K 46 n?: number 47} 48let ctor: Ctor = K 49 50type Spoiler = { nope?: string } 51type Weak = { 52 a?: number 53 properties?: { 54 b?: number 55 } 56} 57declare let propertiesWrong: { 58 properties: { 59 wrong: string 60 } 61} 62let weak: Weak & Spoiler = propertiesWrong 63 64