[英]Change the inference by adding a type assertion in Typescript
From: https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-inference来自: https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-inference
TypeScript doesn't assume the assignment of
1
to a field which previously had0
is an error.TypeScript 不假定将
1
分配给以前为0
的字段是错误的。 Another way of saying this is thatobj.counter
must have the typenumber
, not0
, because types are used to determine both reading and writing behavior.另一种说法是
obj.counter
必须具有类型number
,而不是0
,因为类型用于确定读取和写入行为。The same applies to strings:
这同样适用于字符串:
const req = { url: "https://example.com", method: "GET" }; handleRequest(req.url, req.method); // Argument of type 'string' is not assignable to parameter of type '"GET" | "POST"'.
I thought "GET" is a default value assigned to variable 'method' of the object 'req'.我认为“GET”是分配给 object 'req' 的变量 'method' 的默认值。 What is the error saying?
错误在说什么?
You can change the inference by adding a type assertion in either location:
您可以通过在任一位置添加类型断言来更改推理:
// Change 1: const req = { url: "https://example.com", method: "GET" as "GET" }; // Change 2 handleRequest(req.url, req.method as "GET");
Change 1 means “I intend for
req.method
to always have the literal type"GET"
”, preventing the possible assignment of"GUESS"
to that field after.更改 1 的意思是“我打算让
req.method
始终具有文字类型"GET"
”,从而防止之后可能将"GUESS"
分配给该字段。 Change 2 means “I know for other reasons thatreq.method
has the value"GET"
“.更改 2 的意思是“由于其他原因,我知道
req.method
的值为"GET"
”。
What do they mean by adding a type assertion in this case?在这种情况下添加类型断言是什么意思?
What is happening here?这里发生了什么?
If you hover over req
, you'll see that method
is a string.如果你 hover over
req
,你会看到这个method
是一个字符串。 The types have been "widened".类型已“扩大”。 You have to find a way to tell Typescript not to do that.
你必须想办法告诉 Typescript 不要那样做。 One of these is using
const
.其中之一是使用
const
。
const req = { url: "https://example.com", method: "GET" } as const;
Or you can explicitly say that method
is either "GET" or "POST".或者您可以明确地说该
method
是“GET”或“POST”。
const req: { url: string, method: "GET" | "POST" } = { url: "https://example.com", method: "GET" as "GET" };
or using type assertion like you did as
.或者像你一样使用类型断言
as
。 (We are often told not to use type assertions but that's a good use case) (我们经常被告知不要使用类型断言,但这是一个很好的用例)
This would work as well这也可以
const req = { url: "https://example.com", method: "GET" as const }; // const just on method
This little example will help you understand better what's happening:这个小例子将帮助您更好地理解正在发生的事情:
let num = 3 //number since you can assign something else to num
const num = 3 //3 since it's a const (not supposed to change)
When creating req
, you're basically creating an object with an url: string
and method: string
.创建
req
时,您基本上是在使用url: string
和method: string
创建 object。 Here's an example equal to your code:这是一个与您的代码相同的示例:
interface Request {
url: string;
method: string;
}
const req: Request = { url: "https://example.com", method: "GET" };
handleRequest(req.url, req.method);
but this way, you can't ensure that method
is GET or POST, so if handleRequest expects one of those values it will complain if you pass a "string", which could equal to anything.但这样一来,您无法确保该
method
是 GET 或 POST,因此如果 handleRequest 期望其中一个值,如果您传递一个“字符串”,它会报错,它可能等于任何值。
A solution could be to define a type for the req, for example:一个解决方案可能是为 req 定义一个类型,例如:
interface Request {
url: string;
method: 'GET' | 'POST';
}
// or using 'type' if you prefer
// type Request = {
// url: string;
// method: 'GET' | 'POST';
// }
const req: Request = { url: "https://example.com", method: "GET" };
handleRequest(req.url, req.method);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.