Skip to content

Instantly share code, notes, and snippets.

@gunar
Last active March 7, 2019 23:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gunar/414e0dcfbb424e2099fefdb6fa6880b0 to your computer and use it in GitHub Desktop.
Save gunar/414e0dcfbb424e2099fefdb6fa6880b0 to your computer and use it in GitHub Desktop.
// Proof: https://www.typescriptlang.org/play/#src=type%20Woman%20%3D%20%7B%0D%0A%20%20id%3A%20Number%0D%0A%20%20husband%3F%3A%20string%0D%0A%7D%0D%0A%0D%0Atype%20With%3CT%2C%20K%20extends%20keyof%20T%3E%20%3D%20(Required%3CPick%3CT%2C%20K%3E%3E%20%26%20Exclude%3CT%2C%20K%3E)%0D%0Atype%20Without%3CT%2C%20K%20extends%20keyof%20T%3E%20%3D%20Pick%3CT%2C%20Exclude%3Ckeyof%20T%2C%20K%3E%3E%0D%0A%0D%0Aconst%20processMrs%20%3D%20(mrs%3A%20With%3CWoman%2C%20'husband'%3E)%20%3D%3E%20%7B%0D%0A%20%20%20%20const%20%7B%20husband%20%7D%20%3D%20mrs%0D%0A%20%20%20%20console.log(%60I%20now%20for%20a%20fact%20%24%7Bmrs%7D%20is%20married.%60)%0D%0A%7D%0D%0AprocessMrs(%7B%20id%3A%201%2C%20husband%3A%20'John'%20%7D)%20%20%20%20%2F%2F%20passes%0D%0AprocessMrs(%7B%20id%3A%202%2C%20husband%3A%20undefined%20%7D)%20%2F%2F%20fails%20(with%20strictNullChecks%3A%20true)%0D%0AprocessMrs(%7B%20id%3A%203%20%7D)%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20fails%20(with%20strictNullChecks%3A%20true)%0D%0A%0D%0Aconst%20processMs%20%3D%20(ms%3A%20Without%3CWoman%2C%20'husband'%3E)%20%7B%0D%0A%20%20console.log(%60I%20know%20for%20a%20fact%20%24%7Bms%7D%20is%20not%20married.%60)%0D%0A%7D%0D%0AprocessMs(%7B%20id%3A%201%2C%20husband%3A%20'John'%20%7D)%20%20%20%20%2F%2F%20fails%20(with%20strictNullChecks%3A%20true)%0D%0AprocessMs(%7B%20id%3A%202%2C%20husband%3A%20undefined%20%7D)%20%2F%2F%20fails%20(with%20strictNullChecks%3A%20true)%0D%0AprocessMs(%7B%20id%3A%203%20%7D)%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20passes%0D%0A%0D%0A%2F%2F%20%40gunar%202018-03-07%0D%0A%2F%2F%20https%3A%2F%2Fmedium.com%2F%40gunar%2Fnarrower-optional-fields-for-typescript-49fd68335601
type Woman = {
id: Number
husband?: string
}
type With<T, K extends keyof T> = (Required<Pick<T, K>> & Exclude<T, K>)
type Without<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
const processMrs = (mrs: With<Woman, 'husband'>) => {
const { husband } = mrs
console.log(`I now for a fact ${mrs} is married.`)
}
processMrs({ id: 1, husband: 'John' }) // passes
processMrs({ id: 2, husband: undefined }) // fails (with strictNullChecks: true)
processMrs({ id: 3 }) // fails (with strictNullChecks: true)
const processMs = (ms: Without<Woman, 'husband'>) {
console.log(`I know for a fact ${ms} is not married.`)
}
processMs({ id: 1, husband: 'John' }) // fails (with strictNullChecks: true)
processMs({ id: 2, husband: undefined }) // fails (with strictNullChecks: true)
processMs({ id: 3 }) // passes
@gunar
Copy link
Author

gunar commented Mar 7, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment