Flow类型转换表达式(Type Casting Expressions)

类型转换表达式(Type Casting Expressions)

声明与转换值成各种类型

有时候并不需要像函数或变量一样声明类型,Flow支持内联类型转换表达式的语法。

类型转换语法

围绕一个值创建一个类型转换表达式的方式是:(:type)

(value: Type)

注:括号是避免与其他语法混淆的必要条件。

类型转换表达式可以在任何允许表达式存在的地方出现。

let val = (value: Type);
let obj = { prop: (value: Type) };
let arr = ([(value: Type), (value: Type)]: Array<Type>);

值本身可以是表达式:

(2 + 2: number);

类型声明

使用类型转换表达式,你可以把值声明成特定的类型。

// @flow
let value = 42;

(value: 42);     // Works!
(value: number); // Works!
(value: string); // Error!

类型转换

当你编写一个类型转换表达式时,该表达式的结果是提供的值的类型。 并且会不断返回新的类型。

// @flow
let value = 42;

(value: 42);     // Works!
(value: number); // Works!

let newValue = (value: number);

// $ExpectError
(newValue: 42);     // Error!
(newValue: number); // Works!

通过any进行类型转换

由于类型转换与所有其他类型注释的工作方式相同,因此只能将值转换为较不具体的类型。你不能更改类型或使其更具体。

但是你可以使用any类型来转换成你想要的任何类型。

let value = 42;

(value: number); // Works!
// $ExpectError
(value: string); // Error!

let newValue = ((value: any): string);

// $ExpectError
(newValue: number); // Error!
(newValue: string); // Works!

通过将值赋予任何值,然后可以转换成任何你想要的。这是不安全的,不推荐。但是当你做某些非常困难或不可能输入的值,并且要确保结果具有所需的类型时,有时候这会很有用。

例如,以下的cloneObject函数。

function cloneObject(obj) {
  const clone = {};

  Object.keys(obj).forEach(key => {
    clone[key] = obj[key];
  });

  return clone;
}

我们很难为此创建一个类型,因为我们正在创建一个基于另一个对象的新对象。但如果我们通过any进行转换,我们可以返回一个更有用的类型。

// @flow
function cloneObject(obj) {
  const clone = {};

  Object.keys(obj).forEach(key => {
    clone[key] = obj[key];
  });

  return ((clone: any): typeof obj); // <<
}

const clone = cloneObject({
  foo: 1,
  bar: true,
  baz: 'three'
});

(clone.foo: 1);       // Works!
(clone.bar: true);    // Works!
(clone.baz: 'three'); // Works!

通过类型声明检查类型

如果你想验证上面提到的cloneObject函数会接收什么类型,我们可以使用下面的注解:

function cloneObject(obj: { [key: string]: mixed }) {
  // ...
}

但是typeof对象注解会破坏整个目的。

// @flow
function cloneObject(obj: { [key: string]: mixed }) {
  const clone = {};
  // ...
  return ((clone: any): typeof obj);
}

const clone = cloneObject({
  foo: 1,
  bar: true,
  baz: 'three'
});

// $ExpectError
(clone.foo: 1);       // Error!
// $ExpectError
(clone.bar: true);    // Error!
// $ExpectError
(clone.baz: 'three'); // Error!

相反,我们通过使用类型声明表达式在函数内部进行声明。

// @flow
function cloneObject(obj) {
  (obj: { [key: string]: mixed });
  // ...
}

cloneObject({ foo: 1 }); // Works!
// $ExpectError
cloneObject([1, 2, 3]);  // Error!

现在类型推导在type of阶段作用,并且返回对象的形态。

// @flow
function cloneObject(obj) {
  (obj: { [key: string]: mixed }); // <<

  const clone = {};
  // ...
  return ((clone: any): typeof obj);
}

const clone = cloneObject({
  foo: 1,
  bar: true,
  baz: 'three'
});

(clone.foo: 1);       // Works!
(clone.bar: true);    // Works!
(clone.baz: 'three'); // Works!

注意:这不是解决上述问题的恰当方法。 正确的解决方案是这样的注释功能:

function cloneObject<T: { [key: string]: mixed }>(obj: T): $Shape<T> {
 // ...
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,348评论 19 139
  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 14,201评论 0 38
  • { "Unterminated string literal.": "未终止的字符串文本。", "Identifi...
    一粒沙随风飘摇阅读 11,213评论 0 3
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,626评论 9 118
  • A大金融系录取通知书寄到家了,曲以秋终于按着了父母的旨意完读完了高中,完成了高考。 她很清楚自...
    minguogigi阅读 228评论 0 0

友情链接更多精彩内容