Flow: Allow same name in value and type namespace

Created on 3 Oct 2016  路  9Comments  路  Source: facebook/flow

Sorry if this is a duplicate. I looked for awhile and couldn't find anything.

I think it's frequently desirable to have a value (often a constructor, but sometimes a collection of helper functions) and a type to have the same name (as they're about the same thing). This appears to be possible with classes, but could values and types just have completely separate namespaces.

Example of failing code:

// @flow

import * as Arr from 'flow-static-land/lib/Arr'
import type { Arr } from 'flow-static-land/lib/Arr'

With the error "name is already bound"

Most helpful comment

Why this was closed? This is one of those things with Flow which annoys me on daily basis. It does not make sense to suffix the type with info that it's type, it's just unnecessary duplicate information.

Of course if something can act as value and type, it can be in both name spaces; It has a role in both. But plain types should not.

All 9 comments

Yeah, there is a shared namespace between types and values. Considering the way that classes interact with the type system in being both types _and_ values this makes a bit more sense.

Is there a technical reason for the shared namespace? If not, I get the sense you think it's a good idea regardless. If I'm reading that right, would you be able to say a bit about why?

Hi! I'm reading the silence as a hard no. Is that right? If so, should I close the issue? If not, is there anything I should do?

I think this design makes the most sense.. do you think this is still an issue?
Or do you still need a solution to handle Arr as an type import?

Maybe try import typeof { Arr as ArrT } from 'flow-static-land/lib/Arr'?

Hey. I still feel its an issue, though I guess Arr as ArrT isn't the worst.

I'll close this issue for now but feel free to reopen it

Why this was closed? This is one of those things with Flow which annoys me on daily basis. It does not make sense to suffix the type with info that it's type, it's just unnecessary duplicate information.

Of course if something can act as value and type, it can be in both name spaces; It has a role in both. But plain types should not.

It depends on the imported values.

If the imported entity is a class, you can also use it as a type... e.g.

import { Component } from 'react'

const foo: Component = 1; // error because type mismatch

See: https://flowtype.org/try/#0JYWwDg9gTgLgBAbzgYQuCA7Aph+BfOAMyjTgHIosBDAYxjICgGbMBneQiCALhTUmy44AXjgBGANxwgA

There is also now a quite neat syntax sugar how you can mix normal & type imports:

import React, { typeof Component } from 'react';

class Foo extends Component { // This will cause an error, since Component is just a type here
}

See: https://flowtype.org/try/#0JYWwDg9gTgLgBAJQKYEMDGMA0cDecYCeYSEAZnAMITgQB2St8AvnKVNXAORSoacDcAKEFoANigDOEuADEIEOEgAeMBgBNpVGvUa5BcOIKZA

For import * as Whatever, you need to do a type WhateverT = typeof Whatever ,...

I never used it too much and I think it's kinda arcane :-)

This issue should be reopened. It is a show-stopper for people moving from TypeScript to Flow.
TypeScript has distinct namespaces for types and values. Accordingly the following works quite nicely in TypeScript but sadly not in Flow.

type strOrNum = string | number;

function strOrNum(arg: any): strOrNum {
  if (typeof arg !== 'string' && typeof arg !== 'number)
    throw TypeError('Argument is not a string or number')

  return arg;
}

I鈥檇 like to consider this if we implement namespaces, but we feel at the moment that this behavior is correct and encourage you to find different names for your values and types 馃槉

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghost picture ghost  路  3Comments

philikon picture philikon  路  3Comments

jamiebuilds picture jamiebuilds  路  3Comments

ctrlplusb picture ctrlplusb  路  3Comments

pelotom picture pelotom  路  3Comments