Compiler options decide some important aspects of the type checking:
export const enum YourEnum { /*..something here..*/ }
, see https://stackoverflow.com/questions/50564756/exporting-enum-from-typescript-type-definition-file Intersection, e.g. T1 & T2 :
Union, e.g. T1|T2
Type guard is a way to assert type of a value:
Function returns "aParameter is A_TYPE", a type guard, if true, the parameter's type is inferred
function determineIfIsAnimalOrHuman(toBeDetermined: PersonOrAnimal): toBeDetermined is Animal {
if((toBeDetermined as Animal).type){
return true
}
return false
}
Usage
if(determineIfIsAnimalOrHuman(toBePrinted)){
console.log(toBePrinted.type) //inferred toBePrinted is an Animal
}
if ((<Fish>pet).swim) { (<Fish>pet).swim(); }
if ((pet as Fish).swim) {(pet as Fish).swim(); }
if ("swim" in pet) { return pet.swim(); }
about "typeof", it can also be used in type expression to extract the type out from a value
if (typeof padding === "number") {
return Array(padding + 1).join(" ") + value; // compiler knows padding is number now
}
if (value instanceof SomeClass) {
// can use value as SomeClass here
}
To get enum-like behavior with the literals
function greeter(person: string) {} // parameter
let fullName: string // variable, prefer 'const' & 'let', no 'var'
// describe an object
interface Person {
property: string;
optionalProperty?: string; // optional
// variables can be 'const', properties 'readonly'
readonly readonlyProperty: number;
[propName: string]: any; any excessive property allowed
}
// describe a function
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch : SearchFunc;
mySearch = function(.... // actually define the implementation
// indexable types, define index signature (string/number or both)
interface StringArray {
[index: number]: string;
}
let myArray: StringArray;
// define class with method
interface ClockInterface {
currentTime: Date;
setTime(d: Date);
}
// extends one or more interfaces or class (use only signature not implementation)
interface Square extends Shape, PenStroke {
sideLength: number;
}
see
https://www.typescriptlang.org/docs/handbook/declaration-merging.html
'declare' gives a global name - defined somewhere else and without a type - a type. "The declare keyword is used for ambient declarations where you want to define a variable that may not have originated from a TypeScript file."
https://stackoverflow.com/questions/43335962/purpose-of-declare-keyword-in-typescript
https://www.typescriptlang.org/docs/handbook/utility-types.html#parameterst
Partial<T>: a type with all T properties optional
Readonly<T>: all properties of T readonly
Record<K,T>: K is a union (e.g. 'A'|'B'|'C') and T a type, then Record<K,T> is a type with a set of properties with each k in K of type T. When to use, I wonder?
Pick<T,K>: K is a union of keys, T is an interface with many properties, Pick<T,K> has a subset of properties (K) picked from T
Omit<T,K>: not picking, removing
Exclude<T,U>: T be a union, then this is a type removing those assignable to U
Extract<T,U>: T a union, extract all that assignable to U
NonNullable<T>: T a union, excluding values null & undefined (NOTE: unless strictNullChecks compiler option enabled, value of this type can still be null)
Parameters<T>: T be a function, construct a tuple type of the types of the parameters of a function type T
export type PropsType = Parameters<Parameters<typeof registerSettingsPage>[0]>[0]
ConstructorParameters<T>: T a constructor function
ReturnType<T>: T a function
InstanceType<T>: T a constructor function, this is the instance type, e.g. type T0 = InstanceType<typeof C>; // C
Required<T>: turn all properties required
ThisParaeterType<T>: T a function with 'this' parameter
OmitThisParameter<T>: return function without 'this' parameter
ThisType<T>: do nothing, just a marker
(see above)
The "? :" expression works on types as well as values.
The "infer" keyword extracts the type at the place.
Combined, see example below.
// if T is an array of type R, type R, or just T
type FlattenIfArray<T> = T extends (infer R)[] ? R : T
// if T is a promise, the promised type, or just T
type Unpromisify<T> = T extends Promise<infer R> ? R : T
https://dev.to/aexol/typescript-tutorial-infer-keyword-2cn