Open zabojad opened 4 years ago
Something like this?
abstract MyDynamicStruct(Dynamic) {
public inline function new(knownField:String) {
this = {knownField:knownField};
}
public var knownField(get,never):String;
inline function get_knownField():String
return this.knownField;
@:arrayAccess inline function get(name:String):InjectedShape
return Reflect.field(this, name);
@:arrayAccess inline function set(name:String, v:InjectedShape):InjectedShape {
Reflect.setField(this, name, v);
return v;
}
}
usage
var o = new MyDynamicStruct('hello');
trace(o.knownField); // hello
o['dynamicField'] = new InjectedShape();
trace(o['dynamicField']); // stringified InjectedShape instance
We can probably implement something like
typedef MyDynamicStruct = { knownField:String } & Dynamic<Int>;
Opinions?
Yes please! (with support for Dynamic<Any>
too of course)
@RealyUniqueName thank you for your replies.
Just for illustrating my need, I was wondering how to translate this typescript interface into a haxe extern: react-intl's injectIntl
Your first proposition doesn't help me in my particular case as I'm never actually building the MyDynamicStruct object as it is the extern lib which does that.
haxe typedef MyDynamicStruct = { knownField:String } & Dynamic<Int>;
I'm sorry but I do not understand this notation :
What I need would probably look more like how we declare type parameters, however not for declaring a generic type but rather for declaring a property name instead:
typedef WrappedComponentProps<DynPropName = 'defaultPropName'> = {
[DynPropName]: SomeKnownShape;
};
... that we could extend from in other typedef:
typedef MyCompProps = {
> WrappedComponentProps<'intl'>,
myCompPublicProp:String,
// ...
}
That could be limited to externs only if that makes it more feasible :D...
There's not much you can do without making wrapComponent
a macro; you cannot use a runtime value from options
argument to build a compile-time type otherwise
Yhea obviously, it's too tricky...
And what does Dynamic<Int>
means? For me and until now, Dynamic was simply Dynamic :)... Does it "reduce" the Dynamic to allow it to have only unknown number of Int
fields?
@kLabz it's too tricky but thinking about it, it feasible with typescript and there's no runtime checking with ts neither... However the way it's feasible is very verbose I agree:
type WrappedComponentProps<IntlPropName extends string = 'intl'> = {
[k in IntlPropName]: IntlShape;
};
type WithIntlProps<P> = Omit<P, keyof WrappedComponentProps> & {
forwardedRef?: React.Ref<any>;
};
function injectIntl<
IntlPropName extends string = 'intl',
P extends WrappedComponentProps<IntlPropName> = WrappedComponentProps<any>
>(
WrappedComponent: React.ComponentType<P>,
options?: Opts<IntlPropName>
): React.ComponentType<WithIntlProps<P>> & {
WrappedComponent: typeof WrappedComponent;
};
Then I also think it is anyway an edge case and we can probably live without such feature anyway...
Dynamic<T>
has been around for a long time, you can find out more about it on https://haxe.org/manual/types-dynamic-with-type-parameter.html
Yhea, I rarely used Dynamic (as less as I can) and never realized there was a type parameter...
I'm currently writing an extern for some js lib and I'm facing the following case:
How could I type a prop with a dynamic name with Haxe 4.1? With a default value would be even better...