Intro
When I write codes, I often confuse if I should use type alias or interface.Actually, they are quite similar in some situations.
So I want to know how to distinct them.
Environments
- TypeScript ver.3.8.3
- Node.js ver.12.10.0
Similarity
After compiling
Both type alias and interface are only in TypeScript.After compiling to JavaScript, they will be disappeared.
TypeScript
interface ISample{
name: string;
}
type TSample = {
message: string
};
function main() {
const iSample: ISample = {
name: 'Hello'
};
const tSample: TSample = {
message: 'World'
};
}
main();
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function main() {
var iSample = {
name: 'Hello'
};
var tSample = {
message: 'World'
};
}
main();
Treat as same type
If an object has same properties with them, they treat as their type, though the object doesn't implement them explicitly.
function main() {
const iSample = {
name: 'Hello'
};
const iSample2: ISample = iSample; // OK
const tSample = {
message: 'World'
};
const tSample2: TSample = tSample; // OK
}
Class implemmentation
Class can implement them.
/** OK */
class IClassSample implements ISample {
public name: string = 'Hello'
}
/** OK */
class TClassSample implements TSample {
public message: string = 'World'
}
Difference
Declaration merging
Interface has "declaration merging".If there are some interfaces what have same name in same namespace, same file, and etc, they will be merged.
interface ISample{
name: string;
}
interface ISample{
message: string;
}
function main() {
// 1st and 2nd ISample are merged.
const iSample: ISample = {
name: 'Hello',
message: 'World'
};
}
Extends
Only interface can extends type alias and interface.
interface ISample{
name: string;
}
type TSample = {
message: string
};
interface IExtendSample extends ISample, TSample {
id: number;
}
function main() {
const iSample: IExtendSample = {
id: 0,
name: 'Hello',
message: 'World'
};
}
But type alias can Cross type to get similar result.
interface ISample{
name: string;
}
type TSample = {
message: string
};
type TCrossSample = ISample & TSample & { id: number; }
function main() {
const tSample: TCrossSample = {
id: 0,
name: 'Hello',
message: 'World'
};
}
Declare type
Interface is only declared in this way.
interface InterfaceName {
propertyName: Type
};
But type alias can be declared in many kinds of type.
interface ISample{
name: string;
}
type TSample = {
message: string
};
/** Union type */
type TUnionSample = ISample|TSample;
/** Cross type */
type TCrossSample = ISample & TSample & { id: number; }
/** Tuple */
type TTupleSample = [string, number];
/** Function */
type TFunctionSample = (message: string) => void;
/** Object */
type TObjectSample = {
message: string
};
/** Mapped type */
type TBase = {
id: number,
name: string
};
type TMappedSample = { [P in keyof TBase]: string; };
/** Conditional type */
type TConditionalSample<T> = T extends string? 'string': 'other';
function main() {
const crossSample: TCrossSample = {
id: 0,
name: 'Hello',
message: 'World'
};
const tupleSample: TTupleSample = ['hello', 0];
const mappedSample: TMappedSample = {
id: '0',
name: 'Hello'
};
const conditionalSample: TConditionalSample<string> = 'string';
}
Inteface also can create some types like type alias.For example, interface can create function type like item12 of "Effective TypeScript".
interface IFunctionSample {
(message: string): void
}
type TFunctionSample = (message: string) => void;
const callIFunction: IFunctionSample = (message) => console.log(message);
const callTFunction: TFunctionSample = (message) => console.log(message);
function main() {
callIFunction('Hello'); // OK
callTFunction('World'); // OK
}
But the others that are like Union type etc. cannot.When should I use "type"?
When I can use either, should I use type alias?According to "Effective TypeScript", I should follow the project style.
And if I need to publish to other projects, I should choose interface.
When the project is for a web application, if the object is for detecting behaviour and implemented by class, I want to choose interface.
If the object is for saving some data like data transfer object, I want to choose type alias.
Maybe this is because I get used to write C# codes :)
References
TypeScript/spec.md at master · microsoft/TypeScript · GitHubAdvanced Types · TypeScript
Effective TypeScript
Interface vs Type alias in TypeScript 2.7 - Martin Hochel - Medium
TypeScript: Interfaces vs Types - Stack Overflow
コメント
コメントを投稿