535
['*', {kind: 'Object', shapeId: BuiltInRefValueId}],
536
]);
537
538
+/**
539
+ * MixedReadOnly =
540
+ * | primitive
541
+ * | simple objects (Record<string, MixedReadOnly>)
542
+ * | Array<MixedReadOnly>
543
+ *
544
+ * APIs such as Relay — but also Flux and other data stores — often return a
545
+ * union of types with some interesting properties in terms of analysis.
546
+ *
547
+ * Given this constraint, if data came from Relay, then we should be able to
548
+ * infer things like `data.items.map(): Array`. That may seem like a leap at
549
+ * first but remember, we assume you're not patching builtins. Thus the only way
550
+ * data.items.map can exist and be a function, given the above set of data types
551
+ * and builtin JS methods, is if `data.items` was an Array, and `data.items.map`
552
+ * is therefore calling Array.prototype.map. Then we know that function returns
553
+ * an Array as well. This relies on the fact that map() is being called, so if
554
+ * data.items was some other type it would error at runtime - so it's sound.
555
+ *
556
+ * Note that this shape is currently only used for hook return values, which
557
+ * means that it's safe to type aliasing method-call return kinds as `Frozen`.
558
+ *
559
+ * Also note that all newly created arrays from method-calls (e.g. `.map`)
560
+ * have the appropriate mutable `BuiltInArray` shape
561
+ */
562
addObject(BUILTIN_SHAPES, BuiltInMixedReadonlyId, [
563
[
564
'toString',
570
returnValueKind: ValueKind.Primitive,
571
}),
572
],
573
+ [
574
+ 'indexOf',
575
+ addFunction(BUILTIN_SHAPES, [], {
576
+ positionalParams: [],
577
+ restParam: Effect.Read,
578
+ returnType: {kind: 'Primitive'},
579
+ calleeEffect: Effect.Read,
580
+ returnValueKind: ValueKind.Primitive,
581
+ }),
582
+ ],
583
+ [
584
+ 'includes',
585
+ addFunction(BUILTIN_SHAPES, [], {
586
+ positionalParams: [],
587
+ restParam: Effect.Read,
588
+ returnType: {kind: 'Primitive'},
589
+ calleeEffect: Effect.Read,
590
+ returnValueKind: ValueKind.Primitive,
591
+ }),
592
+ ],
593
+ [
594
+ 'at',
595
+ addFunction(BUILTIN_SHAPES, [], {
596
+ positionalParams: [Effect.Read],
597
+ restParam: null,
598
+ returnType: {kind: 'Object', shapeId: BuiltInMixedReadonlyId},
599
+ calleeEffect: Effect.Capture,
600
+ returnValueKind: ValueKind.Frozen,
601
+ }),
602
+ ],
603
[
604
'map',
605
addFunction(BUILTIN_SHAPES, [], {
696
addFunction(BUILTIN_SHAPES, [], {
697
positionalParams: [],
698
restParam: Effect.ConditionallyMutate,
645
- returnType: {kind: 'Poly'},
699
+ returnType: {kind: 'Object', shapeId: BuiltInMixedReadonlyId},
700
calleeEffect: Effect.ConditionallyMutate,
647
- returnValueKind: ValueKind.Mutable,
701
+ returnValueKind: ValueKind.Frozen,
702
noAlias: true,
703
mutableOnlyIfOperandsAreMutable: true,
704
}),