"as"关键字是用来做什么的?

216
if (process.env.NODE_ENV !== 'production') {
    (WithUser as any).displayName = wrapDisplayName(Component, 'withUser');
}

我甚至不确定as是否是一个关键字,但无论如何,它在JavaScript中有什么作用呢?


5
可能是在TypeScript中类型断言和新的'as'操作符之间有什么区别?的重复问题。 - L Y E S - C H I O U K H
"as" 是在 TypeScript 中用于类型断言表达式的。 - Prasad
3
可能是 typescript. what is mean: (this as any)的重复问题。 - jonrsharpe
7个回答

285
那不是普通的JavaScript,而是TypeScript。"as any"告诉编译器将有类型的对象视为未经处理的无类型JavaScript对象。
"as"关键字是Type Assertion in TypeScript,它告诉编译器将对象视为与编译器推断的类型不同的另一种类型。

31
请问当断言失败时,as关键字会发生什么?会抛出错误或异常吗? - Grim
31
这里什么都没有。这只是编译器的概念,它告诉编译器将一个对象视为与其推断的类型不同的类型。实际运行的已编译JavaScript没有类型的概念。运行的代码将基于编译后的JavaScript抛出错误和异常。 - Adrian Brand
9
请问您是否能提供您参考过的TypeScript文档,或者任何可以支持这个回答的文档链接? - Jeremy
2
有时候在 TypeScript 应用程序中,当某些对象没有确切的类型时,"as" 是唯一的解决方案。 - Goran_Ilic_Ilke
1
as 的文档 https://basarat.gitbook.io/typescript/type-system/type-assertion - Aleksander Ryhlitski
显示剩余3条评论

53

这不是纯JS,而是 TypeScript。但是对于 as 关键字本身,它被称为类型断言(Type Assertion),你只是在告诉编译器将某个东西视为一种类型:

var a = 'TEST STRING'
var b = a as string; //Means the compiler will assume it's a string

它等价于这个:

var a = 'TEST STRING'
var b = <string> a; 

然而,当使用JSX(JS和HTML标签)时可能会令人困惑,因此在这些情况下,更推荐使用as语法。


5
两者之间有差别吗? var b = 'test' as string; 和 var b: string = 'test' 答案:两者的本质相同,都是将字符串赋值给变量b,并声明它为字符串类型。使用 "as" 关键字是一个类型断言,告诉编译器将 'test' 视为字符串类型。而在 var b: string = 'test' 中,类型注释指定了变量的类型为字符串。 - Embedded_Mugs
2
@Embedded_Mugs 回答你的问题:https://dev59.com/_MLra4cB1Zd3GeqPCiLj?noredirect=1#comment122344292_69220403 - TheSmartMonkey

15

这是一个TypeScript操作符,它在ECMAScript 2015(JavaScript的最新版本)中不可用。

正如上面的答案所指出的,'as'运算符是一种的形式

举个简单的例子,假设你有两种类型:First和Second。您正在编写一个方法,并且该方法不确定您的对象将是哪种类型。它可能是First或Second类型。

因此,您声明变量而不使用严格的类型。一旦您的方法了解了变量应采取的类型,您就可以将其“作为该类型”返回。

尽管似乎有点含糊和模糊,但“as”运算符实际上执行与另一种(更熟悉的)模式完全相同的功能:

这两段代码执行完全相同的操作

    let accountCode = '123';
    let castedAccountCode = <number>accountCode;

使用 as 关键字:

    let accountCode = '123';
    let castedAccountCode = accountCode as number;

1
此代码生成:TS2352:将类型为“string”的值转换为类型“number”可能是一个错误,因为两种类型都不足以重叠。如果这是有意的,请先将表达式转换为“unknown”。 - OSGI Java
1
如果您知道您想要从字符串中获取一个数字,那么为什么不写成这样呢? const accountCode = '123'; const castedAccountCode: number = parseInt(accountCode, 10); - OSGI Java
或者简单地说:const castedAccountCode: number = +accountCode; - Carlos Ribeiro

11
这种类型断言是无用的,因为
function foo (a: string, b: string): number {
    return (a as number) + (b as number)
}

简单转换为

function foo(a, b) {
    return a + b;
}

我最初的期望是它会像这样

function foo(a, b) {
    if (typeof a != 'string') throw ...
    if (typeof b != 'string') throw ...
    return Number(a) + Number(b)
}

但是 TypeScript 给了用户一种错误的安全感。


这可能是因为运算符+也适用于字符串,如果您在签名中将'string'更改为'boolean',则生成的代码相同,但会出现编译器错误。 - QuarK
18
一旦您理解“as”的重点,那么真正的“安全感错误”就不存在了。 - Richard.Davenport
8
as 用于帮助 TypeScript 在编译时检查类型,而不是进行运行时的类型强制转换。 - ABOS
@ABOS 我本来以为第一个代码片段的意思是第三个!!!我现在不明白你的评论想要表达什么!!! - pravin poudel
这就是Typescript的工作方式。您需要理解Typescript中类型空间和值空间之间的区别,才能真正理解“as”的行为。 - Liutong Chen

4

通过 as 进行键映射

在提供的示例中,as 关键字用于 类型断言。在 TypeScript 4.1 及以上版本中,as 关键字不仅可以用于 类型断言,还可以用于键映射

这使您可以重新映射类型的键。例如:

type Person = {
  name: string;
  age: number;
};

type Getters<T> = {
  [K in keyof T as `get${Capitalize<K & string>}`]: () => T[K];
};

type MappedPerson = Getters<Person>;

// type MappedPerson = {
//   getName: () => string;
//   getAge: () => number;
// }

通用和模板文字类型在这里真的很出色。键映射是一个非常强大的功能,因为您还可以将键映射到其值的类型。例如,借助条件类型,可以通过键对应值的类型来过滤对象属性。假设我们想从Person类型中删除所有number类型的属性:

type WithoutPropertiesOfTypeNumber<T> = {
  [K in keyof T as T[K] extends number ? never : K]: T[K];
};

type PersonWithoutPropertiesOfTypeNumbers =
  WithoutPropertiesOfTypeNumber<Person>;

// type PersonWithoutPropertiesOfTypeNumbers = {
//     name: string;
// }

4
正如之前的回答所指出的,原问题中代码中的单词 as 是 TypeScript 中的关键字。不过作为补充说明,在 JavaScript 中,as 是一个上下文关键字,当代码遇到语法规则 ImportClause 时会使用该关键字。

2
在TypeScript中,关键字as用于显式地将一个值强制转换为不同的类型。它允许您告诉TypeScript编译器,您对一个值的类型了解得比它更多,并将该值视为不同类型的值。
例如,考虑以下代码:
let myValue: any = "Hello, world!";
let myLength: number = (<string>myValue).length;

在这段代码中,myValue 的类型是 any,这意味着 TypeScript 对其类型一无所知。我们可以使用 as 关键字告诉 TypeScript,我们知道 myValue 是一个 string,像这样:
let myValue: any = "Hello, world!";
let myLength: number = (myValue as string).length;

这两个示例都可以达到相同的结果,但第二个示例使用 as 关键字进行类型转换。

注意,在使用 as 关键字时,您要告诉 TypeScript 您确定该值的类型。如果您犯了一个错误,将一个值强制转换为错误的类型,可能会导致运行时错误。因此,在使用 as 关键字时要小心,并确保将其转换为正确的类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接