Advanced TypeScript -tyyppien huijauslehti (esimerkkejä)

TypeScript on kirjoitettu kieli, jonka avulla voit määrittää muuttujien tyypin, toimintoparametrit, palautetut arvot ja objektiominaisuudet.

Tässä edistynyt TypeScript Types -huijausarkki esimerkkeineen.

Sukelletaan sisään.

  • Risteystyypit
  • Unionityypit
  • Yleiset tyypit
  • Apuohjelmatyypit
  • Osittainen
  • Vaaditaan
  • Lue ainoastaan
  • Valita
  • Jättää pois
  • Ottaa talteen
  • Sulje pois
  • Ennätys
  • Ei peruutettavissa
  • Kartoitetut tyypit
  • Tyyppiset vartijat
  • Ehdolliset tyypit

Risteystyypit

Risteystyyppi on tapa yhdistää useita tyyppejä yhdeksi. Tämä tarkoittaa, että voit yhdistää tietyn tyypin A tyypin B tai enemmän ja saada takaisin yhden tyypin, jolla on kaikki ominaisuudet.

type LeftType = { id: number left: string } type RightType = { id: number right: string } type IntersectionType = LeftType & RightType function showType(args: IntersectionType) { console.log(args) } showType({ id: 1, left: "test", right: "test" }) // Output: {id: 1, left: "test", right: "test"} 

Kuten näette, IntersectionTypekahdella tapaa - LeftTypeja RightTypeja käyttää &merkkiä rakentaa risteyksessä tyyppi.

Unionityypit

Unionityyppien avulla voit käyttää erityyppisiä merkintöjä tietyssä muuttujassa.

type UnionType = string | number function showType(arg: UnionType) { console.log(arg) } showType("test") // Output: test showType(7) // Output: 7 

Funktio showTypeon unionityyppi, joka hyväksyy sekä merkkijonot että numerot parametrina.

Yleiset tyypit

Geneerinen tyyppi on tapa käyttää tiettyä tyyppiä uudelleen. Se auttaa kaappaamaan Tparametrina syötetyn tyypin .

function showType(args: T) { console.log(args) } showType("test") // Output: "test" showType(1) // Output: 1 

Yleisen tyypin rakentamiseksi sinun on käytettävä suluita ja välitettävä Tparametri.

Tässä käytän T(nimi riippuu sinusta) ja soitan sitten funktiolle showTypekahdesti erityyppisillä huomautuksilla, koska se on yleinen - sitä voidaan käyttää uudelleen.

interface GenericType { id: number name: T } function showType(args: GenericType) { console.log(args) } showType({ id: 1, name: "test" }) // Output: {id: 1, name: "test"} function showTypeTwo(args: GenericType) { console.log(args) } showTypeTwo({ id: 1, name: 4 }) // Output: {id: 1, name: 4} 

Tässä meillä on toinen esimerkki, jolla on käyttöliittymä, GenericTypejoka vastaanottaa yleisen tyypin T. Ja koska se on uudelleenkäytettävä, voimme kutsua sitä ensin merkkijonolla ja sitten numerolla.

interface GenericType { id: T name: U } function showType(args: GenericType) { console.log(args) } showType({ id: 1, name: "test" }) // Output: {id: 1, name: "test"} function showTypeTwo(args: GenericType) { console.log(args) } showTypeTwo({ id: "001", name: ["This", "is", "a", "Test"] }) // Output: {id: "001", name: Array["This", "is", "a", "Test"]} 

Yleinen tyyppi voi vastaanottaa useita argumentteja. Tässä välitetään kaksi parametria: Tja U, ja sitten käytetään niitä tyypin huomautuksina ominaisuuksille. Tästä huolimatta voimme nyt käyttää käyttöliittymää ja tarjota erilaisia ​​argumentteja.

Apuohjelmatyypit

TypeScript tarjoaa käteviä sisäänrakennettuja apuohjelmia, jotka auttavat käsittelemään tyyppejä helposti. Jos haluat käyttää niitä, sinun on siirryttävä muunnettavaan tyyppiin.

Osittainen

  • Partial

Osittainen antaa sinun tehdä kaikista tyypin ominaisuuksista Tvalinnaisia. Se lisää ?merkin jokaisen kentän viereen.

interface PartialType { id: number firstName: string lastName: string } function showType(args: Partial) { console.log(args) } showType({ id: 1 }) // Output: {id: 1} showType({ firstName: "John", lastName: "Doe" }) // Output: {firstName: "John", lastName: "Doe"} 

As you can see, we have an interface PartialType which is used as type annotation for the parameters received by the function showType(). And to make the properties optional, we have to use the Partial keyword and pass in the type PartialType as an argument. That said, now all fields become optional.

Required

  • Required

Unlike Partial, the Required utility makes all properties of the type T required.

interface RequiredType { id: number firstName?: string lastName?: string } function showType(args: Required) { console.log(args) } showType({ id: 1, firstName: "John", lastName: "Doe" }) // Output: { id: 1, firstName: "John", lastName: "Doe" } showType({ id: 1 }) // Error: Type '{ id: number: }' is missing the following properties from type 'Required': firstName, lastName 

The Required utility will make all properties required even if we make them optional first before using the utility. And if a property is omitted, TypeScript will throw an error.

Readonly

  • Readonly

This utility type will transform all properties of the type T in order to make them not reassignable with a new value.

interface ReadonlyType { id: number name: string } function showType(args: Readonly) { args.id = 4 console.log(args) } showType({ id: 1, name: "Doe" }) // Error: Cannot assign to 'id' because it is a read-only property. 

Here, we use the utility Readonly to make the properties of ReadonlyType not reassignable. That said, if you try to give a new value to one of these fields, an error will be thrown.

Besides that, you can also use the keyword readonly in front of a property to make it not reassignable.

interface ReadonlyType { readonly id: number name: string } 

Pick

  • Pick

It allows you to create a new type from an existing model T by selecting some properties K of that type.

interface PickType { id: number firstName: string lastName: string } function showType(args: Pick) { console.log(args) } showType({ firstName: "John", lastName: "Doe" }) // Output: {firstName: "John"} showType({ id: 3 }) // Error: Object literal may only specify known properties, and 'id' does not exist in type 'Pick' 

Pick is a bit different from the previous utilities we have already seen. It expects two parameters - T is the type you want to pick elements from and K is the property you want to select. You can also pick multiple fields by separating them with a pipe(|) symbol.

Omit

  • Omit

The Omit utility is the opposite of the Pick type. And instead of selecting elements, it will remove K properties from the type T.

interface PickType { id: number firstName: string lastName: string } function showType(args: Omit) { console.log(args) } showType({ id: 7 }) // Output: {id: 7} showType({ firstName: "John" }) // Error: Object literal may only specify known properties, and 'firstName' does not exist in type 'Pick' 

This utility is similar to the way Pick works. It expects the type and the properties to omit from that type.

Extract

  • Extract

Extract allows you to construct a type by picking properties that are present in two different types. The utility will extract from T all properties that are assignable to U.

interface FirstType { id: number firstName: string lastName: string } interface SecondType { id: number address: string city: string } type ExtractType = Extract // Output: "id" 

Here, we have two types that have in common the property id. And hence by using the Extract keyword, we get back the field id since it's present in both interfaces. And if you have more than one shared field, the utility will extract all similar properties.

Exclude

Unlike Extract, the Exclude utility will construct a type by excluding properties that are already present in two different types. It excludes from T all fields that are assignable to U.

interface FirstType { id: number firstName: string lastName: string } interface SecondType { id: number address: string city: string } type ExcludeType = Exclude // Output; "firstName" | "lastName" 

As you can see here, the properties firstName and lastName are assignable to the SecondType type since they are not present there. And by using the Extract keyword, we get back these fields as expected.

Record

  • Record

This utility helps you to construct a type with a set of properties K of a given type T. Record is really handy when it comes to mapping the properties of a type to another one.

interface EmployeeType { id: number fullname: string role: string } let employees: Record = { 0: { id: 1, fullname: "John Doe", role: "Designer" }, 1: { id: 2, fullname: "Ibrahima Fall", role: "Developer" }, 2: { id: 3, fullname: "Sara Duckson", role: "Developer" }, } // 0: { id: 1, fullname: "John Doe", role: "Designer" }, // 1: { id: 2, fullname: "Ibrahima Fall", role: "Developer" }, // 2: { id: 3, fullname: "Sara Duckson", role: "Developer" } 

The way Record works is relatively simple. Here, it expects a number as a type which is why we have 0, 1, and 2 as keys for the employees variable. And if you try to use a string as a property, an error will be thrown. Next, the set of properties is given by EmployeeType hence the object with the fields id, fullName, and role.

NonNullable

  • NonNullable

It allows you to remove null and undefined from the type T.

type NonNullableType = string | number | null | undefined function showType(args: NonNullable) { console.log(args) } showType("test") // Output: "test" showType(1) // Output: 1 showType(null) // Error: Argument of type 'null' is not assignable to parameter of type 'string | number'. showType(undefined) // Error: Argument of type 'undefined' is not assignable to parameter of type 'string | number'. 

Here, we pass the type NonNullableType as an argument to the NonNullable utility which constructs a new type by excluding null and undefined from that type. That said, if you pass a nullable value, TypeScript will throw an error.

By the way, if you add the --strictNullChecks flag to the tsconfig file, TypeScript will apply non-nullability rules.

Mapped types

Mapped types allow you to take an existing model and transform each of its properties into a new type. Note that some utility types covered earlier are also mapped types.

type StringMap = { [P in keyof T]: string } function showType(arg: StringMap) { console.log(arg) } showType({ id: 1, name: "Test" }) // Error: Type 'number' is not assignable to type 'string'. showType({ id: "testId", name: "This is a Test" }) // Output: {id: "testId", name: "This is a Test"} 

StringMap will transform whatever types that passed in into a string. That said, if we use it in the function showType(), the parameters received must be a string - otherwise, an error will be thrown by TypeScript.

Type Guards

Type Guards allow you to check the type of a variable or an object with an operator. It's a conditional block that returns a type using typeof, instanceof, or in.

  • typeof
function showType(x: number | string) { if (typeof x === "number") { return `The result is ${x + x}` } throw new Error(`This operation can't be done on a ${typeof x}`) } showType("I'm not a number") // Error: This operation can't be done on a string showType(7) // Output: The result is 14 

As you can see, we have a normal JavaScript conditional block that checks the type of the argument received with typeof. With that in place, you can now guard your type with this condition.

  • instanceof
class Foo { bar() { return "Hello World" } } class Bar { baz = "123" } function showType(arg: Foo | Bar) { if (arg instanceof Foo) { console.log(arg.bar()) return arg.bar() } throw new Error("The type is not supported") } showType(new Foo()) // Output: Hello World showType(new Bar()) // Error: The type is not supported 

Kuten edellinen esimerkki, tämä on myös tyyppisuoja, joka tarkistaa, onko vastaanotettu parametri osa Fooluokkaa vai ei, ja käsittelee sitä vastaavasti.

  • in
interface FirstType { x: number } interface SecondType { y: string } function showType(arg: FirstType | SecondType) { if ("x" in arg) { console.log(`The property ${arg.x} exists`) return `The property ${arg.x} exists` } throw new Error("This type is not expected") } showType({ x: 7 }) // Output: The property 7 exists showType({ y: "ccc" }) // Error: This type is not expected 

inOperaattori voit tarkistaa, onko kiinteistön xolemassa vai ei saamaansa parametrina.

Ehdolliset tyypit

Ehdolliset tyypit testaavat kahta tyyppiä ja valitsevat yhden niistä testin tuloksesta riippuen.

type NonNullable = T extends null | undefined ? never : T 

Tämä esimerkki NonNullableapuohjelmatyypistä tarkistaa, onko tyyppi tyhjä vai ei, ja käsittelee sitä siitä riippuen. Ja kuten huomaat, se käyttää Java-kolmio-operaattoria.

Kiitos lukemisesta.

Löydät muuta tällaista mahtavaa sisältöä blogistani tai seuraa minua Twitterissä saadaksesi ilmoituksen.