简体   繁体   中英

Intersection types vs interfaces in typescript

Here's the scenario:

type Admin = {
    name : string,
    privileges : string[]
}
type Employee ={
    name : string,
    startDate : Date
}

type ElevatedEmployee = Admin & Employee;

const el : ElevatedEmployee ={ // all the properties must be implemented here else compiler will complain
    name : 'Max',
    privileges :['create server'],
    startDate : new Date()
}

I can achieve the same thing using interfaces:

interface Admin {
    name : string,
    privileges : string[]
}

interface Employee {
     name : string,
    startDate : Date
}

interface Combined extends Admin, Employee { 
//this doesn't throw me a compilation error, even though i dont implement those properties here
}

What is the difference between intersection types and interfaces? when to use which one?

1. Performance According to TypeScript performance wiki :

Interfaces create a single flat object type that detects property conflicts, which are usually important to resolve, Intersections on the other hand just recursively merge properties. and in some cases produce never, Interfaces also display consistently better. whereas type aliases to intersections can't be displayed in part of other intersections, Type relationships between interfaces are also cached. as opposed to intersection types as a whole, A final noteworthy difference is that when checking against a target intersection type. every constituent is checked before checking against the "effective"/"flattened" type.

For this reason, extending types with interfaces/extends is suggested over creating intersection types.

Hence, if you are worry about TS performance, consider using interfaces.

2. Tricky difference between interfaces and types

types are indexed by the default whereas interfaces are not. It makes interfaces more safe. Consider this example:

type Admin = {
    name: string,
    privileges: string[]
}

type Employee = {
    name: string,
    startDate: Date
}

type CombinedType = Admin & Employee;

interface CombinedInterface extends Admin, Employee { }

const interfaceData: CombinedInterface = { name: '', privileges: [], startDate: new Date() }
const typeData: CombinedType = { name: '', privileges: [], startDate: new Date() }


const handleType = (obj: Record<string, unknown>) => {
    obj['name'] = 42 // unsafe
}


handleType(interfaceData) // error
handleType(typeData) // ok


See this answer and my article for more context.

As you might have noticed, handleType expects almost any object and it is able to modify/mutate it in an unsafe way. However, if you have an object with interface you can't even pass it to unsafe function.

PS There is a tricky difference between types and interfaces in terms of evaluation, see here , but this is not the case for your example

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM