In the process of touching TS related code, you can always see interface and type. Writing code feels like a bunch of brothers who can achieve the same function with either one. But I’ve been seeing them lately, and I want to know more about them.
1. The interface: the interface
One of TypeScript’s core tenets is type-checking of the structure a value has. Interfaces are used to name these types and define data models for your code or third-party code.
interface ConfigValue {
label: string;
}
function print(labelledObj: ConfigValue) { console.log(labelledObj.label);
}
const Obj = {size: 10, label: "Size 10 Object"};
print(myObj);
Copy the code
The interface is like a name that describes the requirements in the example above.
The interface has the following features:
1.1 Optional Properties
interfaceConfig { color? :string;
}Copy the code
1.2 Read-only Properties
interface Point {
readonly x: number;
}Copy the code
1.3 Redundant Attribute Check to prevent the use of attributes that do not belong to the interface
interface Preson {
name: string; age? :number;
}
let p1:Person = {name: 'Ming'} / / right
let p2:Person = {name: 'Ming', age: 18, sex: 'male'}; / / an error
// Bypass: Redundant attributes do not report errors
1 / / way
let p = {name: 'Ming', age: 18, sex: 'male'};
let p3 = p;
2 / / way
interface Preson {
name: string; age? :number;
[propName: string] :any
}
let p4 = {name: 'Ming', age: 18, sex: 'male'};Copy the code
1.4 Function Types
interface SearchFunc {
(source: string, subString: string) :boolean;
}Copy the code
1.5 Index Type: For arrays
interface StringArray {
[index: number] :string;
}
let myArray: StringArray;
myArray = ["Bob"."Fred"];Copy the code
1.6 Type: Interface of the class type
interface ClockInterface {
currentTime: Date;
setTime(d: Date);
}
class Clock implements ClockInterface {
currentTime: Date;
setTime(d: Date) {
this.currentTime = d;
}
constructor(h: number, m: number) {}}Copy the code
1.7 Inheriting Multiple Interfaces
interface Cat {
eat: string;
}
interface Dog {
pull: string;
}
interface Zoom extends Cat, Dog {
play: string;
}
letzoom = <Zoom>{}; zoom.eat='Eat like crazy; zoom.pull='Crazy pull'; zoom.play='Crazy masturbation';Copy the code
2. Type: indicates the type alias
Type gives a type a new name. Type is sometimes similar to interface, but can work with primitive values (primitives), union types, tuples, and anything else you need to write by hand.
For example:
type Name = string; // Basic type
type NameFun = (a)= > string; / / function
type NameOrRFun = Name | NameFun; // Union type
function getName(n: NameOrRFun) :Name { if (typeof n === 'string') {
return n;
}
return n();
}
Copy the code
Aliasing does not create a new type – it creates a new name to refer to that type. Aliasing basic types is usually useless, although it can be used as a form of documentation.
Like interfaces, type aliases can also be generic – we can add type parameters and pass them to the right of the alias declaration:
type Container<T> = { value: T };
Copy the code
You can also use a type alias to reference yourself in a property:
typeTreeNode<T> = { value: T; left: TreeNode<T>; right: TreeNode<T>; }Copy the code
With cross types, we can create some pretty bizarre types.
type LinkedList<T> = T & { next: LinkedList<T> };
interface Person {
name: string;
}
var people: LinkedList<Person>;
var s = people.name;
var s = people.next.name;
var s = people.next.next.name;
var s = people.next.next.next.name;
Copy the code
However, the type alias cannot appear anywhere on the right side of the declaration.
type Yikes = Array<Yikes>; // error
Copy the code
3.interface vs type
3.1. The Objects/Functions provides
Both can be used to describe the type of an object or function, but the syntax is different.
Interface
interface Point {
x: number;
y: number;
}
interface SetPoint {
(x: number, y: number): void;
}
Copy the code
Type alias
type Point = {
x: number;
y: number;
};
type SetPoint = (x: number, y: number) => void;
Copy the code
3.2. Other Types
Unlike interfaces, type aliases can also be used for other types, such as primitive types (primitive values), union types, and tuples.
// primitive
type Name = string;
// object
type PartialPointX = { x: number; };
type PartialPointY = { y: number; };
// union
type PartialPoint = PartialPointX | PartialPointY;
// tuple
type Data = [number, string];
// dom
let div = document.createElement('div');
type B = typeof div;
Copy the code
3.3. The Extend
Both are extensible, but the syntax is different. Also, note that interface and type aliases are not mutually exclusive. Interfaces can extend type aliases and vice versa.
Interface extends interface
interface PartialPointX { x: number; }
interface Point extends PartialPointX { y: number; }
Copy the code
Type alias extends type alias
type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };
Copy the code
Interface extends type alias
type PartialPointX = { x: number; };
interface Point extends PartialPointX { y: number; }
Copy the code
Type alias extends interface
interface PartialPointX { x: number; }
type Point = PartialPointX & { y: number; };
Copy the code
3.4. The class Implements
Classes can implement interface or type aliases in the same way. Note, however, that classes and interfaces are considered static. Therefore, they do not implement/extend type aliases for named union types.
interface Point {
x: number;
y: number;
}
class SomePoint implements Point {
x: 1;
y: 2;
}
type Point2 = {
x: number;
y: number;
};
class SomePoint2 implements Point2 {
x: 1;
y: 2;
}
type PartialPoint = { x: number; } | { y: number; };
// FIXME: can not implement a union type
class SomePartialPoint implements PartialPoint {
x: 1;
y: 2;
}
Copy the code
3.5 extends the class
A class definition creates two things: the instance type of the class and a constructor. Because classes create types, you can use classes where interfaces are allowed.
class Point {
x: number;
y: number;
}
interface Point3d extends Point {
z: number;
}
Copy the code
3.6. Declaration merging
Unlike a type alias, an interface can be defined multiple times and will be treated as a single interface (merging all declared members).
// These two declarations become:
// interface Point { x: number; y: number; }
interface Point { x: number; }
interface Point { y: number; }
const point: Point = { x: 1, y: 2 };
Copy the code
3.7. Calculate attributes and generate mapping types
Type can use the in keyword to generate mapping types, but interface cannot.
Syntax and index the syntax type of the signature, internally using for.. The in. It has three parts:
- Type variable K, which is bound to each property in turn.
- The Keys of the string literal union, which contains the collection of property names to iterate over.
- The result type of the property.
type Keys = "firstname" | "surname"
type DudeType = {
[key in Keys]: string
}
const test: DudeType = {
firstname: "Pawel",
surname: "Grzybek"} //interface DudeType2 {// [keyinKeys]: string //Copy the code
export default interface Config {
name: string
}
// export default typeConfig1 = {// name: string //} // An error is reportedtype Config2 = {
name: string
}
export default Config2
Copy the code
conclusion
Interface is very similar to Type, and can be used in many scenarios. But there are subtle differences:
- Type: Objects, functions are both applicable, but type can be used for base types, union types, and primitives.
- Merge with the same name: Interface is supported, type is not.
- Compute attributes: Type is supported, interface is not.
In general, the public implementation of interface, can not be implemented with interface implementation of type implementation. A pair of good brothers who help each other.
Reference:
- TypeScript- Interface to Chinese documents
- TypeScript- A high-level type for Chinese documents
- TypeScript- Declarative merging of Chinese documents
- Typescript: Interfaces vs Types
- TYPESCRIPT INTERFACE VS. TYPE
- Sample? – Why do you worry about CNblogs