This article introduces the advanced uses of TypeScript. For those who are familiar with TypeScript or have been using TypeScript for some time, it introduces TypeScript from the perspectives of types, operators, generics.
Types
unknown
unknown
refers to a type that cannot be defined in advance. In many scenarios, it can replace the functionality of any while preserving the ability to statically check.
const num: number = 10;
(num as unknown as string).split('');
Note that static checks are just as valid here as any. You can cast it to any type. The difference is that when compiled statically, unknown cannot call any method, whereas any can.
const foo: unknown = "string";
foo.substr(1); // Error: static check does not pass error
const bar: any = 10;
any.substr(1); // Pass: skip static checking
one use case of unknown
is to avoid the static type checking bug caused by using any
as the parameter type of a function:
function test(input: unknown): number {
if (Array.isArray(input)) {
return input.length; // Pass: The type guard has identified the input as an array type
}
return input.length; // Error: input is of unknown type. static check error
}
void
In TypeScript, void
has a similar to undefined
, which logically avoids the error of accidentally using a null pointer.
function foo() {} // The default return type is void
const bar = foo(); // bar's type is defined as void, and you can't call any of property methods of bar
The biggest difference between void
and undefined
is that you can think of undefined
as a subset of void
, and use void
instead of undefined
when you don't care about the return value of a function. Take a practical example from React.
// Child.tsx
type Props = {
getValue: () => void; // number、string、undefined etc.
}
function Child({ getValue }: Props) => <div>{getValue()}</div>
// Parent.tsx
function Parent(): JSX.Element {
const getValue = (): number => {
return 2;
}; /* number type */
// const getValue = (): string => { return 'str' }; /* string type also enable to pass child */
return <Child getValue={getValue} />;
}
never
never
is a type that cannot be returned normally, as a function that is bound to report an error or an infinite loop returns.
function foo(): never {
throw new Error("error message");
} // throw error return type is never
function foo(): never {
while (true) {}
} // infinite loop return type is never
function foo(): never {
let count = 1;
while (count) {
count++;
}
} // Error: it is not directly recognized at static compilation time.
There are also types that never intersect:
type human = "boy" & "girl"; // human is never type
Any type combined with the never type remains the same:
type language = "javascript" | never; // language is string type
never has the following features
After you call a function that returns never in a function, all subsequent code becomes
deadcode
.
function foo(): never {
throw new Error("error message");
}
function test() {
foo();
console.log(111); // Error
}
No other type can be assigned to never.
let n: never;
let o: any = {};
n = o; // Error: cannot assign a non-never type to a never type, including any
Operators
not null assertion operator !
It helps the compiler that I'm sure this is not a null or undefined variable.
let foo: { bar: string } | null | undefined;
// the baz type is string
let baz = foo!.bar; // we tell compiler we are sure foo is not null & not undefined so the type of baz is string
optional chaining
We can use ?.
for safe reading and deleting, but not writing.
obj?.prop // object
obj?.[0] // array
func?.(args) // function
Let's say we write a?.b
, the compiler automatically generates the following code.
a === null || a === void 0 ? void 0 : a.b;
nullish coalescing operator ??
??
is used to return the first non-null (not null or not undefined) value.
const nullValue = null;
const emptyText = ""; // falsy
const someNumber = 42;
const valA = nullValue ?? "default for A"; // "default for A"
const valB = emptyText ?? "default for B"; // "default for B"
const valC = someNumber ?? 0; // 42
keyof
keyof can take all the keys of a type and return a string or numeric literal union of its keys.
type Person = {
name: string;
age: number;
}
type PersonKey = keyof Person; // "name" | "age"
typeof can also get the typeof an object/instance
const me: Person = { name: 'jstyro', age: 16 };
type P = typeof me; // { name: string; age: number; }
const you: typeof me = { name: 'jstyro-two', age: 69 } //
This article is original, without authorization, any media or personal we media and any statement reproduced
Commercial infringement will be investigated, if you need authorization please contact[email protected]
The original link:https://www.jstyro.com/blog/advanced-usage-of-ts