34
loading...
This website collects cookies to deliver better user experience
Awaited
type that improves asynchronous programming, supported lib from node_modules for painless upgrades, and performance optimization by using the realpathSync.native
function.--experimental
flag in the nightly builds of TypeScript.promise.all
, this feature introduces a new Awaited
type useful for modeling operations like await
in async
functions, or the .then()
method on a Promise
.promise.all
, promise.race
, promise.allSettled
, and promise.any
to support the new Awaited
type.PromiseLike
to resolve promise-like “thenables”never
// basic type = string
type basic = Awaited<Promise<string>>;
// recursive type = number
type recursive = Awaited<Promise<Promise<number>>>;
// union type = boolean | number
type union = Awaited<string | Promise<number>>;
.d.ts
. These files don’t compile to .js
; they are only used for type-checking.string
or function
, that are available in the JavaScript language.lib.[something].d.ts
, and they enable Typescript to work well with the version of JavaScript our code is running on.startsWith
string method is available on ES6 and above_.target
value.{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
}
}
target
value is es5
. Thus, ES6 features like startsWith
and the arrow
function cannot be used in our code. To use ES6 features, we can vary which lib files are loaded by changing es5
to es6
.lib
. This method works by looking at a scoped @typescript/lib-*
package in node_modules
:"dependencies": {
"@typescript/lib-dom": "npm:@types/web"
}
}
@types/web
represents TypeScript’s published versions of the DOM APIs. And by adding the code above to our package.json
file, we lock our project to the specific version of the DOM APIs.type TrimLeft<T extends string> = T extends ` ${infer Rest}` ? TrimLeft<Rest> : T;
type Test = TrimLeft<" fifty spaces">;
TrimLeft
type eliminates leading spaces from string type, but if this leading space exceeds 50 (as in the case above), TypeScript throws this error:// error: Type instantiation is excessively deep and possibly infinite.
<!-- A .svelte File -->
<script>
import { someFunc } from "./some-module.js";
</script>
<button on:click={someFunc}>Click me!</button>
<!-- A .vue File -->
<script setup>
import { someFunc } from "./some-module.js";
</script>
<button @click="someFunc">Click me!</button>
script
tags. On the contrary, TypeScript only sees code within the script
tags, consequently it cannot detect the use of the imported someFunc
module. So in the case above, TypeScript would drop the someFunc
import, resulting in unwanted behavior.--preserveValueImports
flag. This flag prevents TypeScript from removing any import in our outputted JavaScript.--preserveValueImports
prevents the TypeScript compiler from removing useful imports, when working with type import, we need a way to tell the TypeScript compiler to remove them. Type imports are imports that only include TypeScript types and are therefore not needed in our JavaScript output.// Which of these is a value that should be preserved? tsc knows, but `ts.transpileModule`,
// ts-loader, esbuild, etc. don't, so `isolatedModules` issues an error.
import { FC, useState } from "react";
const App: FC<{ message: string }> = ({ message }) => (<div>{message}</div>);
FC
is a type import, but from the syntax, there is no way to tell the TypeScript compiler or build tools to drop FC
and preserve useState
.import type { FC } from "react";
import { useState } from "react";
import {type FC, useState} from "react";
type Types =
{
type: `${string}_REQUEST`;
}
| {
type: `${string}_SUCCESS`;
response: string;
};
function reducer2(data: Types) {
if(data.type === 'FOO_REQUEST') {
console.log("Fetcing data...")
}
if (data.type === 'FOO_SUCCESS') {
console.log(data.response);
}
}
console.log(reducer2({type: 'FOO_SUCCESS', response: "John Doe"}))
Types
down because it is a template string type. So accessing data.response
throws an error:- Property 'response' does not exist on type 'Types'.
- Property 'response' does not exist on type '{ type: `${string}_REQUEST`; }'.
class Person {
#password = 12345;
static hasPassword(obj: Object) {
if(#password in obj){
// 'obj' is narrowed from 'object' to 'Person'
return obj.#password;
}
return "does not have password";
}
}
hasPassword
static method uses the in
operator to check if obj
has a private field and returns it.- Property '#password' does not exist on type 'Object'.
import
and dynamic import
as seen below:// normal import
import json from "./myModule.json" assert { type: "json" };
// dynamic import
import("myModule1.json", { assert: { type: "json" } });
any
:Buffer
) and give us a warning when we hover over it as seen below:await
in TypeScript. And this means we can use await
outside of async functions.none
, commonjs
, amd
, system
, umd
,es6
, es2015
, esnext
.--module
option to esnext
or nodenext
enables us to use top-level await, but the es2022
option is the first stable target for this feature.realpathSync.native
function in Node.js on all operating systems. Formally this was used on Linux, but if you are running a recent Node.js version, this function would now be used.@type
tag, we can provide type hints in our code.// type is { readonly name: "John Doe" }
let developer = { name: "John Doe" } as const;
as const
after a literal — this is const
assertion.// type is { readonly prop: "hello" }
let developer = /** @type {const} */ ({ name: "John Doe" });