31
loading...
This website collects cookies to deliver better user experience
NonNullable
, Parameters
, ConstructorParameters
, ReturnType
, InstanceType
, ThisParameterType
, OmitThisParameter
and ThisType
.Partial
, Required
, Readonly
, Record
, Pick
, Omit
, Exclude
and Extract
. Otherwise, keep reading.<>
), follow right after the name of the utility type. The name of the type always starts with capital letter. This is very similar to calling a normal JavaScript function. You only swapped the parentheses for brackets and started the function name with a capital letter.,
). That's about the syntax. Now, let's talk about the actual types.NonNullable
utility type works similarly to the exclude. It takes some type you specified and returns that type excluding all null
and undefined
types.// Create a type:
type prop = string | number | string[] | number[] | null | undefined
// Create new type based on previous type
// excluding null and undefined:
type validProp = NonNullable<prop>
// Translates to:
// type validProp = string | number | string[] | number[]
// This is valid:
let use1: validProp = 'Jack'
let use2: validProp = null
// TS error: Type 'null' is not assignable to type 'validProp'.
Parameters
type returns a tuple type that contains the types of the parameters function you passed as Type
. These parameters are returned in the same order in which they appear in the function. Note that the Type
argument, in case of this and following types, is a function ((...args) => type
), not a type such as string
.// Declare a function type:
declare function myFunc(num1: number, num2: number): number
// Use Parameter type to create new tuple type
// from parameters of myFunc function:
type myFuncParams = Parameters<typeof myFunc>
// Translates to:
// type myFuncParams = [num1: number, num2: number]
// This is valid.
let someNumbers: myFuncParams = [13, 15]
let someMix: myFuncParams = [9, 'Hello']
// TS error: Type 'string' is not assignable to type 'number'.
// Use Parameter type to create new tuple type
// from function type:
type StringOnlyParams = Parameters<(foo: string, fizz: string) => void>
// Translates to:
// type StringOnlyParams = [foo: string, fizz: string]
// This is valid.
let validNamesParams: StringOnlyParams = ['Jill', 'Sandy']
let invalidNamesParams: StringOnlyParams = [false, true]
// TS error: Type 'boolean' is not assignable to type 'string'.
ConstructorParameters
type is very similar to the Parameters
type. The difference between these two is that while Parameters
gets types from function arguments, the ConstructorParameters
gets types from the constructor you pass as the Type
argument.// Create a class:
class Human {
public name
public age
public gender
constructor(name: string, age: number, gender: string) {
this.name = name;
this.age = age;
this.gender = gender;
}
}
// Create type based on Human constructor:
type HumanTypes = ConstructorParameters<typeof Human>
// Translates to:
// type HumanTypes = [name: string, age: number, gender: string]
const joe: HumanType = ['Joe', 33, 'male']
const sandra: HumanType = ['Sandra', 41, 'female']
const thomas: HumanType = ['Thomas', 51]
// TS error: Type '[string, number]' is not assignable to type '[name: string, age: number, gender: string]'.
// Source has 2 element(s) but target requires 3.
// Create type based on Human constructor:
type StringType = ConstructorParameters<StringConstructor>
// Translates to:
// type StringType = [value?: any]
ReturnType
is also similar to the Parameters
type. Difference here is that the ReturnType
extracts the return type of a function you pass as the Type
argument.// Declare type for function:
declare function myFunc(name: string): string
// Use ReturnType to extract return type
// from myFunc type.
type MyFuncReturnType = ReturnType<typeof myFunc>
// Translates to:
// type MyFuncReturnType = string
// This is valid:
let name1: MyFuncReturnType = 'Victoria'
// This is valid:
let name2: MyFuncReturnType = 42
// TS error: Type 'number' is not assignable to type 'string'.
type MyReturnTypeBoolean = ReturnType<() => boolean>
// Translates to:
// type MyReturnTypeBoolean = boolean
type MyReturnTypeStringArr = ReturnType<(num: number) => string[]>
// Translates to:
// type MyReturnTypeStringArr = string[]
type MyReturnTypeVoid = ReturnType<(num: number, word: string) => void>
// Translates to:
// type MyReturnTypeVoid = void
InstanceType
is a bit complicated. What it does is it creates a new type from the instance type of a constructor function you passed as argument for Type
. You will probably don't need this utility type if you work class with a regular class. You can just use the class name to get the instance type you want.class Dog {
name = 'Sam'
age = 1
}
type DogInstanceType = InstanceType<typeof Dog>
// Translates to:
// type DogInstanceType = Dog
// Similar to using the class declaration:
type DogType = Dog
// Translates to:
// type DogType = Dog
ThisParameterType
extracts the type of use for the this
parameter for the function you passed as the Type
argument. If the function doesn't have this
parameter, the utility type will return unknown
.// Create a function with this parameter:
function capitalizeString(this: String) {
return this[0].toUpperCase + this.substring(1).toLowerCase()
}
// Create type based on capitalizeString function this parameter:
type CapitalizeStringType = ThisParameterType<typeof capitalizeString>
// Translates to:
// type CapitalizeStringType = String
OmitThisParameter
utility type does the opposite of the previous type. It takes a function type as an argument, via the Type
, and returns the function type without this
parameter.// Create a function with this parameter:
function capitalize(this: String) {
return this[0].toUpperCase + this.substring(1).toLowerCase()
}
// Create type based on capitalizeString function:
type CapitalizeType = OmitThisParameter<typeof capitalize>
// Translates to:
// type CapitalizeType = () => string
// Create a function without this parameter:
function sayHi(name: string) {
return `Hello, ${name}.`
}
// Create type based on sayHi function:
type SayHiType = OmitThisParameter<typeof sayHi>
// Translates to:
// type SayHiType = (name: String) => string
ThisType
utility type allows you to explicitly set the this
context. You can use it to set this
for whole object literals or just a single function. Before you try this, make sure you have the compiler flag —-noImplicitThis
enabled.// Create interface for this in user object:
interface User {
username: string;
email: string;
isActivated: boolean;
printUserName(): string;
printEmail(): string;
printStatus(): boolean;
}
// Create user object and set this type to User interface:
const userObj: ThisType<User> = {
username: 'Andreas',
email: '[email protected]',
isActivated: false,
printUserName() {
return this.username
},
printEmail() {
return this.email
},
printStatus() {
return this.isActivated
}
}
// Create User interface:
interface User {
username: string;
password: string;
}
// Create SuperUser interface:
interface SuperUser {
clearanceLevel: string;
accesses: string[];
}
// Create type RegularUser by combining User and SuperUser.
// Make properties in User required
// and properties in SuperUser optional:
type RegularUser = Required<User> & Partial<SuperUser>
// This is valid:
const joeJoe: RegularUser = {
username: 'joejoe',
password: 'some_secret_password_unlike_123456',
}
// Also valid:
const jane: RegularUser = {
username: 'jane',
password: 'foo_bar_usually-doesnt_work-that_well',
clearanceLevel: 'A'
}
// This will not work:
const pietro: RegularUser = {
username: 'pietro'
}
// TS error: Type '{ username: string; }' is not assignable to type 'RegularUser'.
// Property 'password' is missing in type '{ username: string; }' but required in type 'Required<User>'.(