- Published on
TypeScript usage notes
- Reading time
- 2 分钟
- Page view
- -
- Author

- Name
- Yicong
- Github
The first time I came into contact with TypeScript was when I was just starting to work and had to write Angular. At that time, I didn’t even understand JavaScript, let alone TypeScript. I followed the gourd and wrote "AnyScript". The only feeling at the time was that this thing was so difficult to use. Why did I add so many restrictions to myself.
Later, when selecting a new project, I chose Vue2, which used JavaScript, and this somewhat torturous experience was over. As time goes by, during the development process, I actually miss TypeScript from time to time. I always feel that it would be more convenient to use it instead of JavaScript.
But at this time, I still had only a limited understanding of TypeScript and only knew how to use basic type annotations. So I made up my mind and read through the Handbook on the official website. I occasionally practiced it when maintaining old projects. I felt that it was more handy to use and had some new understandings. Here I record the points that I think are worth noting during the reading process. I will continue to update the pitfalls and some usage experience during the use process.
1. Literal Inference
Error Example
When using literal types, the following errors are likely to occur
declare function handleRequest(url: string, method: "GET" | "POST"): void;
const req = { url: "https://example.com", method: "GET" };
handleRequest(req.url, req.method);
The above code will report an error:
Argument of type 'string' is not assignable to parameter of type '"GET" | "POST"'.
Why? Because the method in req will be inferred to be of type string instead of the value GET. Between the creation of req and the call to handleRequest, req.method can be copied again, so it will be judged as an error by TypeScript.
How to solve it?
- Method 1: Use assertions in any of the following positions to fix the type of
methodto theGetvalue
// Position 1:
const req = { url: "https://example.com", method: "GET" as "GET" };
// Position 2:
handleRequest(req.url, req.method as "GET");
- Method 2: Use assertions when defining
reqto convert the entire object to a literal type
const req = { url: "https://example.com", method: "GET" } as const;
handleRequest(req.url, req.method);
2. Truthiness narrowing
Although the final values of the two lines of code below are both true, TypeScript will infer that the type of the first line is Boolean, and the type of the second line is the literal true
Boolean("hello"); // type: boolean, value: true
!!"world"; // type: true, value: true
3. Destructuring assignment
When using destructuring assignment, you can use the following three methods to set the type
- Method 1:
function greet(person: { name: string; age: number }) {
return "Hello " + person.name;
}
- Method 2:
interface Person {
name: string;
age: number;
}
function greet(person: Person) {
return "Hello " + person.name;
}
- Method 3:
type Person = {
name: string;
age: number;
};
function greet(person: Person) {
return "Hello " + person.name;
}
However, it should be noted that the type cannot be set directly in the deconstructed object
function draw({ shape: Shape, xPos: number = 100 /*...*/ }) {
render(shape);
}
In JavaScript, the shape: Shape syntax means getting the value of the shape property and renaming it to Shape. Obviously, TypeScript cannot conflict with the original JavaScript syntax, so the above code will report an error: Cannot find name 'shape'. Did you mean 'Shape'?
4. Read-only properties and read-only arrays
In TypeScript, you can use the readonly keyword to mark a property as read-only
interface SomeType {
readonly prop: string;
}
function doSomething(obj: SomeType) {
// Can read
console.log(`prop has the value '${obj.prop}'.`);
// Cannot assign
obj.prop = "hello";
// Cannot assign to 'prop' because it is a read-only property.
}
It is worth noting that TypeScript takes readonly into account when checking whether two types are compatible
interface Person {
name: string;
age: number;
}
interface ReadonlyPerson {
readonly name: string;
readonly age: number;
}
let writablePerson: Person = {
name: "Person McPersonface",
age: 42,
};
// Normal operation
let readonlyPerson: ReadonlyPerson = writablePerson;
console.log(readonlyPerson.age); // -> '42'
writablePerson.age++;
console.log(readonlyPerson.age); // -> '43'
This is different from the read-only array type. The assignment between read-only arrays and regular arrays is not bidirectional.
let x: readonly string[] = [];
let y: string[] = [];
x = y;
y = x;
// The type 'readonly string[]' is 'readonly' and cannot be assigned to the mutable type 'string[]'.