Last active
March 24, 2017 03:19
-
-
Save hraban/66c1778cdd31868034b12db93fcce41c to your computer and use it in GitHub Desktop.
Checked subset typing in TypeScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Imagine you want to explicitly define which members of a public API | |
// interface your implementation actually uses. Example: you implement | |
// a web extension, but only use a few of the members on the argument | |
// to the onHeadersReceived handler. Explicitly typing this is useful | |
// when creating mocks in your unit tests. | |
// | |
// Here's now you could do it: | |
// Inverse keyword of "extends": ensure every member of type Sub exists | |
// on type Super. | |
function EnsureSubsetType<Sub, Super extends Sub>() {} | |
// Explicit list of fields we use from the webrequest API. | |
interface ResponseDetails { | |
url: string; | |
requestId: string; | |
tabId: number; | |
responseHeaders?: chrome.webRequest.HttpHeader[]; | |
} | |
EnsureSubsetType<ResponseDetails, chrome.webRequest.WebResponseDetails>(); // this does actual checking | |
export class MyPlugin { | |
// ... | |
onHeadersReceived(details: ResponseDetails) { | |
// use only the fields on details which you defined above | |
} | |
// ... | |
} | |
// Try adding a random field in the struct above and see the type | |
// checking line fail. | |
// | |
// This makes unit testing MyPlugin easier. Without it, if I call the | |
// onHeadersReceived method in my unit test, I'm not sure which fields | |
// I _actually_ need to mock. Now the typechecker tells me. Without it, | |
// I'd be mocking all kinds of unnecessary detailed fields which my | |
// plugin doesn't actually need. | |
// | |
// Limitation: this does not work for optional members! the responseHeaders field | |
// above could be called anything or have any type and it would pass the typecheck. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Neat trick 👍