admin管理员组文章数量:1332339
Suppose I'm writing code that handles UUIDs. Internally, I want to represent them as strings. That is, every UUID is a string, but not every string is a valid UUID, and I don't want to accidentally assign the wrong thing to a variable meant to hold a UUID. So I want to create a type 'uuid' such that this assignment would fail:
let foo: uuid = "Some string"
But this should succeed:
function create_uuid(): uuid; { /* implementation? */ }
let foo: uuid = create_uuid();
let bar: string = uuid; // this is fine
Is there any way to create a type with Flow that has these properties? I found $Subtype
in my research, and thought this might work:
type uuid = $Subtype<string>;
But for some reason it still allows assignment from a string.
Suppose I'm writing code that handles UUIDs. Internally, I want to represent them as strings. That is, every UUID is a string, but not every string is a valid UUID, and I don't want to accidentally assign the wrong thing to a variable meant to hold a UUID. So I want to create a type 'uuid' such that this assignment would fail:
let foo: uuid = "Some string"
But this should succeed:
function create_uuid(): uuid; { /* implementation? */ }
let foo: uuid = create_uuid();
let bar: string = uuid; // this is fine
Is there any way to create a type with Flow that has these properties? I found $Subtype
in my research, and thought this might work:
type uuid = $Subtype<string>;
But for some reason it still allows assignment from a string.
Share Improve this question asked Nov 12, 2016 at 1:52 JoshJosh 2,0893 gold badges20 silver badges30 bronze badges 1- AFAIK, flow can not define some specific subtype of a string. e.g. it can never differentiate between "Some String" and "uuid chars". They are equivalent subtypes of a string. – Red Mercury Commented Nov 12, 2016 at 3:19
3 Answers
Reset to default 6There is the following hack (the downside is that a UUID
will be also an Object
):
// keep this constructor private
class IsUUID {}
export type UUID = string & IsUUID;
export function create(): UUID {
const uuid = 'blah' // <= your implementation
return ((uuid: any): UUID)
}
// tests
declare function f(uuid: UUID): void;
declare function g(s: string): void;
declare function h(o: Object): void;
let foo = create()
let bar: string = foo // <= ok
f(foo) // <= ok
f(bar) // <= error: string. This type is inpatible with IsUUID
g(foo) // <= ok
g(bar) // <= ok
h(foo) // <= ok :(
Edit: This answer is out of date. Flow has implemented opaque types since this question was asked. Refer to ESRogs' answer.
There may be some hacks that can solve this problem, but what you are asking for is known as an opaque data type and Flow does not currently support them. Here are some discussions of them on the Flow repository on GitHub.
Use an opaque type with a subtyping constraint. From the docs:
exports.js
export opaque type ID: string = string;
imports.js
import type {ID} from './exports';
function formatID(x: ID): string {
return "ID: " + x; // Ok! IDs are strings.
}
function toID(x: string): ID {
return x; // Error: strings are not IDs.
}
https://flow/en/docs/types/opaque-types/
本文标签: javascriptSubtyping builtin types in FlowStack Overflow
版权声明:本文标题:javascript - Subtyping built-in types in Flow - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742330575a2454612.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论