-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow string literal type alias in $PropertyType #2310
Comments
I'm sure that this is a really hard problem, but I wonder if declare class Record<T: Object> {
static <T: Object>(spec: T, name?: string): Class<T & Record<T>>;
get<K: $Keys<T>>(key: K): $PropertyType<T, K>;
set<A>(key: $Keys<T>, value: A): T & Record<T>;
remove(key: $Keys<T>): T & Record<T>;
} Currently, Flow complains that I see that a problem is that K is currently a subtype of a string Union, but it could still be a union itself. get<K: $Keys<T> & $StringLiteral>(key: K): $PropertyType<T, K>; |
I've tried to make this work in User Space, but it hasn't worked. The closest I've got is to get the union of all value types in an Object. So type $Object<V> = {[key: string]: V}
type _$Values<V, O: $Object<V>> = V
type $Values<O: Object> = _$Values<*, O> Using this in the Immutable.js Record type: declare class Record<T: Object> {
static <T: Object>(spec: T, name?: string): Class<T & Record<T>>;
construtor(spec: T): this;
get(key: $Keys<T>): $Values<T>;
set<A>(key: $Keys<T>, value: A): T & Record<T>;
remove(key: $Keys<T>): T & Record<T>;
} This gives us slightly better results. import {Record} from 'immutable'
type P = {
name: string,
age: string
}
const Person = Record({name: 'John Doe', age: '25'})
var bob: Record<P> = new Person({name: 'Bob', age: '31'})
;(bob.get('name'): string) // no error here, but flow doesn't infer the type automatically.
// manual typecasting is still required
;(bob.get('name'): number) // Flow Error: it's a string not a number |
@samwgoldman would allowing a string literal type also allow what @nmn is asking for? Being able to do |
So are there any plans to introduce $Values utility type? |
as a point of reference, Typescript 2.1 introduced the ability to type
|
You can use type Key = 'key';
type T = { key: number };
declare var prop: $ElementType<T,Key>; |
This looks very promising, @calebmer. However, the following code doesn't typecheck for me: export type SomeType = {
aString: string,
aNumber: number,
};
function f2<S: $Keys<SomeType>>(
propertyName: S,
value: $ElementType<SomeType, S>,
) {
};
function f1<S: $Keys<SomeType>>(
propertyName: S,
value: $ElementType<SomeType, S>,
) {
f2(propertyName, value);
};
f1("aNumber", 2); If |
$ElementType Doesn't type-check asd I would expect when used as a return-value: Type checking fails in Foo.getValue(), arguing that the return type of ValueOf is incompatible with each of "number", "string", and "object type" in turn.
A work-around is to use $Subtype
|
@calebmer can you elaborate what are the differences between $PropertyType and $ElementType? My little test says there are no differences: https://flow.org/try/#0C4TwDgpgBA8gRgKygXigbwFBSmATgezAC50A7AVwFsSLK4JcBfDZjACjVpIEYAmAZkYkAJAFEANhEoRSwACrgIAHngIANFADkeQpoB8ASgDc7TlR4ChUYQAUCkXKAWQViDdvv7jQA |
Actual output:
Expected:
No error
The text was updated successfully, but these errors were encountered: