最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - flow types with constant strings, and dependent types - Stack Overflow

programmeradmin0浏览0评论

Say I have the following constant string:

export default const FOO = 'FOO'

Say I import this in a flow annotated file like so:

import FOO from '../consts/Foo'

I then have a function:

const example = (foo : string) : {| type: FOO, foo: string |} => {
  return {type: FOO, foo: foo}
}

This doesn't typecheck with:

  6: const example = (foo : string) : {| type: FOO, foo: string |}=> {
                                                         ^^^^^^^^^^^^^^ string. Ineligible value used in/as type annotation (did you forget 'typeof'?)
  6: const example = (foo : string) : {| type: FOO, foo: string |}=> {
                                                         ^^^^^^^^^^^^^^ FOO

So my questions are:

1) is it possible to use constants in flow types, how can I reproduce this behaviour?

2) Is it possible to do dependent types in flow? so for example, could I encode, through types, that the string that is returned must be the same string that is passed into the example function?

EDIT: Clarification to part 2: Is it possible to in some way indicate that the foo parameter passed into the example function is in fact the same string as the string at the foo key in the return object? Or to assert that the input and output have the same length (for say a shift cipher function). Or say contain a permutation of the same characters? (for a shuffle).

Say I have the following constant string:

export default const FOO = 'FOO'

Say I import this in a flow annotated file like so:

import FOO from '../consts/Foo'

I then have a function:

const example = (foo : string) : {| type: FOO, foo: string |} => {
  return {type: FOO, foo: foo}
}

This doesn't typecheck with:

  6: const example = (foo : string) : {| type: FOO, foo: string |}=> {
                                                         ^^^^^^^^^^^^^^ string. Ineligible value used in/as type annotation (did you forget 'typeof'?)
  6: const example = (foo : string) : {| type: FOO, foo: string |}=> {
                                                         ^^^^^^^^^^^^^^ FOO

So my questions are:

1) is it possible to use constants in flow types, how can I reproduce this behaviour?

2) Is it possible to do dependent types in flow? so for example, could I encode, through types, that the string that is returned must be the same string that is passed into the example function?

EDIT: Clarification to part 2: Is it possible to in some way indicate that the foo parameter passed into the example function is in fact the same string as the string at the foo key in the return object? Or to assert that the input and output have the same length (for say a shift cipher function). Or say contain a permutation of the same characters? (for a shuffle).

https://en.wikipedia.org/wiki/Dependent_type

Share Improve this question edited Apr 12, 2018 at 14:02 Peter Hall 58.7k15 gold badges164 silver badges227 bronze badges asked Feb 13, 2017 at 1:27 Abraham PAbraham P 15.5k13 gold badges63 silver badges130 bronze badges 1
  • If you want FOO to have type 'FOO' then you'll need to declare it, otherwise it's just a string. For the objects, you'd then do type: typeof FOO like the error says. I'm not quite sure what you're asking in your 2) point though. Then you'd end up with an object with two properties with the same string value. – loganfsmyth Commented Feb 13, 2017 at 7:12
Add a comment  | 

2 Answers 2

Reset to default 11

Instead of declaring FOO as a const, declare it as a disjoint union with just one branch:

type FOO = "FOO"

Then your code can be updated like this:

const example = (foo : string) : {| type: FOO, foo: string |} => {
  return {type: "FOO", foo: foo}
}

If you use any value besides the exact string literal "FOO" where a FOO is required, then it is a compile error.

If you would prefer to keep your constant, then you'll need to name the type differently, as they would collide. So you could do:

const FOO = "FOO"
type FooType = "FOO";

const example = (foo : string) : {| type: FooType, foo: string |} => {
  return {type: FOO, foo: foo}
}

Unfortunately, I can't see a way to avoid duplicating the string literal, because type disjoint union definition syntax only permits literals and types, not variables even if they are constants.

Found a workaround for the issue, Instead of using flow type inference we can specify the literal type

export default const FOO:'FOO' = 'FOO'

then in the function you can use as

const example = (foo : string) : {| type: typeof FOO, foo: string |} => {
return {type: FOO, foo: foo}
}

Because when you declare the constant type is inferred to be string also I believe flow doesn't support setting type definitions from variables or constants.

发布评论

评论列表(0)

  1. 暂无评论