I know those of us that have been using other strongly typed languages like C# for years want to use I to prefix interfaces. We have been doing so for years, so why stop now? Well, you don’t have to stop, but if you were the population that wasn’t willing to change you probably wouldn’t be using Typescript…So why change? It feels good, sure, it seems right, granted, but it isn’t.
By using the “I” as you always have you are doing yourself and your TS code a disservice and will likely run into issues, because it is likely masking a knowledge gap. The separation between classes, interfaces and types just isn’t there like in other languages. So when you go to make IProps for your react classes, just call it Props, even for interfaces, not just for “types”. You can use a class or a type instead of an interface and typescript will not mind a bit, thus Interfaces do not need a separate prefix to set them apart.
Here is what I have found in our code bases:
Situation 1: Simple props being passed in:
interface IProps {
greeting: string,
}
export class InterfacesAreFun extends React.Component<IProps, never> {
render() {
return <span>The old world: IProps: {this.props.greeting}</span>
}
}
Situation 2: Using Redux with React with dispatch actions:
interface IProps {
greeting: string,
}
interface IPropsDispatch {
fetchGreeting: () => void,
}
type Props = IProps & IPropsDispatch;
export class InterfacesAreFun extends React.Component<Props, never> {
render() {
return <span>The old world: IProps: {this.props.greeting}</span>
}
}
//omitting the Redux binding code
Thus we had the “I” prefix for interfaces but not for types. But in the end, the “type” and the “interface” really can be used the same way and the differentiation is completely wasted. The point is that in your code, you don’t care if it is an Interface or not, what you care about is that it is a type (not the keyword “type” but just the generic concept, “type”).
Without the “I”
Now in reality you are probably going to want to export the “IProps” interface, and not the IPropsDispatch (unless the Redux mapping is being done in a different file if you are separating out the component from the redux mapping). Thus having an interface named Props isn’t probably a good idea anyway, so let’s fix that and see it without the “I”:
export interface PropsForFun {
greeting: string,
}
interface PropsDispatch {
fetchGreeting: () => void,
}
type Props = PropsForFun & PropsDispatch;
export class InterfacesAreFun extends React.Component<Props, never> {
render() {
return <span>The old world: IProps: {this.props.greeting}</span>
}
}
I added the export to props interface and changed the name to “PropsForFun”. This can then be easily used by the component that wants to render the InterfacesAreFun class.
If you want to read more about removing the “I” prefix, this is another good article: Hey TypeScript, where’s my I-prefixed interface!. To enforce not having the “I” prefix standard in your code add this rule to your TSLint file:
"rules": { "interface-name" : [true, "never-prefix"] }
Other sources include the Typescript coding repo itself has the standard of not having an I prefix, and the general community agrees that is the correct way of doing it.
Now, at the end of the day, once you understand that you don’t need “I” as a prefix and why you don’t need it, if it is in your coding standards and you have lots of existing code or others think about “I” all day, it’s okay to roll with it. I would rather you understand why you don’t need it and choose it anyway then to choose to remove it without understanding why.