Typescript - More on Functions (1)
更新時間: 2023/07/24
Function Type Expressions
// `(a: string) => void` is the type of fn
function greeter(fn: (a: string) => void) {
fn("Hello, World");
}
// can also use type alias to name a type function
type GreetFunction = (a: string) => void;
// And then we can use GreetFunction to replace `(a: string) => void`
function greeter(fn: GreetFunction) {
fn("Hello, World");
}
Call Signatures
// functions can have properties in addition to being callable -- call signature
// syntax use `:` between parameter list and return type (rather than using `=>`)
type DescribableFunction = {
description: string;
(someArg: number): boolean;
}
function doSomething(fn: DescribableFunction) {
console.log(`${fn.description} returned ${fn(6)}`)
}
function myFunc(someArg: number) {
return someArg > 3;
}
myFunc.description = "default description";
doSomething(myFunc);
Construct Signatures
Use new keyword in front of a call signature to write a construct signature
type SomeConstructor = {
new (s: string): SomeObject;
};
function fn(ctor: SomeConstructor) {
return new ctor("hello");
}
// Some objects can be called with / without `new` (ex: Date())
// Can combine call and construct signatures
interface CallOrConstruct {
new (s: string): Date;
(n?: number): string;
}
Generic Functions
// This works but it returns `any`
function firstElement(arr: any[]) {
return arr[0];
}
// when defining generic functions can declare a `type parameter` in the function signature
// The `Type` here link between the input of the function and the output
function firstElement<Type>(arr: Type[]): Type | undefined {
return arr[0];
}
Inference
The type was inferred - chosen automatically - by TypeScript
Constraints
To limit the kinds of types that a type parameter can accept
// extend `length` to `Type`
// ex: when the input is error, it will show error because number doesn't have `length`
function longest<Type extends { length: number }>(a: Type, b: Type) {
if (a.length >= b.length) {
return a;
} else {
return b;
}
}
Common error when using constraint
function miniumLength<Type extends { length: number }>(
obj: Type,
minium: number
): Type { // should return the same kind of object that passed in
if(obj.length >= minium) {
return obj;
} else {
return { length: minimum };
// error here, should be same kind of object that passed in not some object matches the constraint
}
}