Previously, I wrote a markdown-related component that inserted the string generated by the back-end parsing of markdown into the DOM via
dangerouslySetInnerHTML, and set a number of styles that were introduced via modular CSS.
It had been working fine before, but recently I had another page that needed to be styled the same as the markdown page, and of course the most intuitive way to do that is to just bring up the style file, but an interesting question comes to mind here: is it also not possible for the props of a component, or the parameters of a function, to be type-safe and defined as mutually exclusive?
The same component, without children, passing only a props named content, is rendered differently than the case where no content is passed, but a child component.
Or, as an example of a function.
Of course, even without TypeScript, JS itself allows functions to be called with a mismatch to their definition.
You can tell if a parameter is passed by determining if it is
undefined, and in
TypeScript you can define both parameters as optional. But if this code is in a third-party library, you can only expect the user to read the documentation and follow the conventions. Is there a type-safe way to do this?
Union types Union Types can be defined in
But it is useless to define the parameters directly as the union type of two interfaces.
Some languages have a type system where there is a bottom type that is a subtype of all types. In
TypeScript, there is such a type,
never, which can be used to represent the return value (or lack thereof) of a function that only throws exceptions or internal dead loops. It has the property that no value of any other type can be assigned to a variable of this type.
Using this property, the above code is modified to.
This ensures that the user will only use one of the two mutually exclusive properties, and a simple conditional rendering within the component will do the trick.