美文网首页
Flow类型转换表达式(Type Casting Express

Flow类型转换表达式(Type Casting Express

作者: vincent_z | 来源:发表于2018-01-27 16:06 被阅读0次

类型转换表达式(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> {
 // ...
}

相关文章

网友评论

      本文标题:Flow类型转换表达式(Type Casting Express

      本文链接:https://www.haomeiwen.com/subject/xawnaxtx.html