Skip to content

Commit 4fb88cd

Browse files
CraigMacomberanthony-murphy-agent
authored andcommitted
Fix metadata types (microsoft#25736)
## Description SchemaFactoryBeta incorrectly gave insufficiently specific types for schema metadata, and passed tests due to a bug in how the tests were written.
1 parent 36ebe10 commit 4fb88cd

File tree

9 files changed

+158
-23
lines changed

9 files changed

+158
-23
lines changed

packages/dds/tree/api-report/tree.alpha.api.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -926,9 +926,9 @@ export class SchemaFactoryAlpha<out TScope extends string | undefined = string |
926926

927927
// @beta
928928
export class SchemaFactoryBeta<out TScope extends string | undefined = string | undefined, TName extends number | string = string> extends SchemaFactory<TScope, TName> {
929-
object<const Name extends TName, const T extends RestrictiveStringRecord<ImplicitFieldSchema>, const TCustomMetadata = unknown>(name: Name, fields: T, options?: ObjectSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, TreeObjectNode<T, ScopedSchemaName<TScope, Name>>, object & InsertableObjectFromSchemaRecord<T>, true, T>;
929+
object<const Name extends TName, const T extends RestrictiveStringRecord<ImplicitFieldSchema>, const TCustomMetadata = unknown>(name: Name, fields: T, options?: ObjectSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, TreeObjectNode<T, ScopedSchemaName<TScope, Name>>, object & InsertableObjectFromSchemaRecord<T>, true, T, never, TCustomMetadata>;
930930
// (undocumented)
931-
objectRecursive<const Name extends TName, const T extends RestrictiveStringRecord<System_Unsafe.ImplicitFieldSchemaUnsafe>, const TCustomMetadata = unknown>(name: Name, t: T, options?: ObjectSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, System_Unsafe.TreeObjectNodeUnsafe<T, ScopedSchemaName<TScope, Name>>, object & System_Unsafe.InsertableObjectFromSchemaRecordUnsafe<T>, false, T>;
931+
objectRecursive<const Name extends TName, const T extends RestrictiveStringRecord<System_Unsafe.ImplicitFieldSchemaUnsafe>, const TCustomMetadata = unknown>(name: Name, t: T, options?: ObjectSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, System_Unsafe.TreeObjectNodeUnsafe<T, ScopedSchemaName<TScope, Name>>, object & System_Unsafe.InsertableObjectFromSchemaRecordUnsafe<T>, false, T, never, TCustomMetadata>;
932932
record<const T extends TreeNodeSchema | readonly TreeNodeSchema[]>(allowedTypes: T): TreeNodeSchemaNonClass<ScopedSchemaName<TScope, `Record<${string}>`>, NodeKind.Record, TreeRecordNode<T> & WithType<ScopedSchemaName<TScope, `Record<${string}>`>, NodeKind.Record>, RecordNodeInsertableData<T>, true, T, undefined>;
933933
record<const Name extends TName, const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(name: Name, allowedTypes: T, options?: NodeSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Record, TreeRecordNode<T> & WithType<ScopedSchemaName<TScope, Name>, NodeKind.Record>, RecordNodeInsertableData<T>, true, T, undefined, TCustomMetadata>;
934934
recordRecursive<Name extends TName, const T extends System_Unsafe.ImplicitAllowedTypesUnsafe, const TCustomMetadata = unknown>(name: Name, allowedTypes: T, options?: NodeSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Record, TreeRecordNodeUnsafe<T> & WithType<ScopedSchemaName<TScope, Name>, NodeKind.Record, unknown>, {

packages/dds/tree/api-report/tree.beta.api.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,9 +483,9 @@ export const SchemaFactory_base: SchemaStatics & (new () => SchemaStatics);
483483

484484
// @beta
485485
export class SchemaFactoryBeta<out TScope extends string | undefined = string | undefined, TName extends number | string = string> extends SchemaFactory<TScope, TName> {
486-
object<const Name extends TName, const T extends RestrictiveStringRecord<ImplicitFieldSchema>, const TCustomMetadata = unknown>(name: Name, fields: T, options?: ObjectSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, TreeObjectNode<T, ScopedSchemaName<TScope, Name>>, object & InsertableObjectFromSchemaRecord<T>, true, T>;
486+
object<const Name extends TName, const T extends RestrictiveStringRecord<ImplicitFieldSchema>, const TCustomMetadata = unknown>(name: Name, fields: T, options?: ObjectSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, TreeObjectNode<T, ScopedSchemaName<TScope, Name>>, object & InsertableObjectFromSchemaRecord<T>, true, T, never, TCustomMetadata>;
487487
// (undocumented)
488-
objectRecursive<const Name extends TName, const T extends RestrictiveStringRecord<System_Unsafe.ImplicitFieldSchemaUnsafe>, const TCustomMetadata = unknown>(name: Name, t: T, options?: ObjectSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, System_Unsafe.TreeObjectNodeUnsafe<T, ScopedSchemaName<TScope, Name>>, object & System_Unsafe.InsertableObjectFromSchemaRecordUnsafe<T>, false, T>;
488+
objectRecursive<const Name extends TName, const T extends RestrictiveStringRecord<System_Unsafe.ImplicitFieldSchemaUnsafe>, const TCustomMetadata = unknown>(name: Name, t: T, options?: ObjectSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, System_Unsafe.TreeObjectNodeUnsafe<T, ScopedSchemaName<TScope, Name>>, object & System_Unsafe.InsertableObjectFromSchemaRecordUnsafe<T>, false, T, never, TCustomMetadata>;
489489
record<const T extends TreeNodeSchema | readonly TreeNodeSchema[]>(allowedTypes: T): TreeNodeSchemaNonClass<ScopedSchemaName<TScope, `Record<${string}>`>, NodeKind.Record, TreeRecordNode<T> & WithType<ScopedSchemaName<TScope, `Record<${string}>`>, NodeKind.Record>, RecordNodeInsertableData<T>, true, T, undefined>;
490490
record<const Name extends TName, const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(name: Name, allowedTypes: T, options?: NodeSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Record, TreeRecordNode<T> & WithType<ScopedSchemaName<TScope, Name>, NodeKind.Record>, RecordNodeInsertableData<T>, true, T, undefined, TCustomMetadata>;
491491
recordRecursive<Name extends TName, const T extends System_Unsafe.ImplicitAllowedTypesUnsafe, const TCustomMetadata = unknown>(name: Name, allowedTypes: T, options?: NodeSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Record, TreeRecordNodeUnsafe<T> & WithType<ScopedSchemaName<TScope, Name>, NodeKind.Record, unknown>, {

packages/dds/tree/api-report/tree.legacy.beta.api.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -486,9 +486,9 @@ export const SchemaFactory_base: SchemaStatics & (new () => SchemaStatics);
486486

487487
// @beta
488488
export class SchemaFactoryBeta<out TScope extends string | undefined = string | undefined, TName extends number | string = string> extends SchemaFactory<TScope, TName> {
489-
object<const Name extends TName, const T extends RestrictiveStringRecord<ImplicitFieldSchema>, const TCustomMetadata = unknown>(name: Name, fields: T, options?: ObjectSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, TreeObjectNode<T, ScopedSchemaName<TScope, Name>>, object & InsertableObjectFromSchemaRecord<T>, true, T>;
489+
object<const Name extends TName, const T extends RestrictiveStringRecord<ImplicitFieldSchema>, const TCustomMetadata = unknown>(name: Name, fields: T, options?: ObjectSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, TreeObjectNode<T, ScopedSchemaName<TScope, Name>>, object & InsertableObjectFromSchemaRecord<T>, true, T, never, TCustomMetadata>;
490490
// (undocumented)
491-
objectRecursive<const Name extends TName, const T extends RestrictiveStringRecord<System_Unsafe.ImplicitFieldSchemaUnsafe>, const TCustomMetadata = unknown>(name: Name, t: T, options?: ObjectSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, System_Unsafe.TreeObjectNodeUnsafe<T, ScopedSchemaName<TScope, Name>>, object & System_Unsafe.InsertableObjectFromSchemaRecordUnsafe<T>, false, T>;
491+
objectRecursive<const Name extends TName, const T extends RestrictiveStringRecord<System_Unsafe.ImplicitFieldSchemaUnsafe>, const TCustomMetadata = unknown>(name: Name, t: T, options?: ObjectSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, System_Unsafe.TreeObjectNodeUnsafe<T, ScopedSchemaName<TScope, Name>>, object & System_Unsafe.InsertableObjectFromSchemaRecordUnsafe<T>, false, T, never, TCustomMetadata>;
492492
record<const T extends TreeNodeSchema | readonly TreeNodeSchema[]>(allowedTypes: T): TreeNodeSchemaNonClass<ScopedSchemaName<TScope, `Record<${string}>`>, NodeKind.Record, TreeRecordNode<T> & WithType<ScopedSchemaName<TScope, `Record<${string}>`>, NodeKind.Record>, RecordNodeInsertableData<T>, true, T, undefined>;
493493
record<const Name extends TName, const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(name: Name, allowedTypes: T, options?: NodeSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Record, TreeRecordNode<T> & WithType<ScopedSchemaName<TScope, Name>, NodeKind.Record>, RecordNodeInsertableData<T>, true, T, undefined, TCustomMetadata>;
494494
recordRecursive<Name extends TName, const T extends System_Unsafe.ImplicitAllowedTypesUnsafe, const TCustomMetadata = unknown>(name: Name, allowedTypes: T, options?: NodeSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Record, TreeRecordNodeUnsafe<T> & WithType<ScopedSchemaName<TScope, Name>, NodeKind.Record, unknown>, {

packages/dds/tree/src/simple-tree/api/schemaFactoryBeta.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@ export class SchemaFactoryBeta<
8888
TreeObjectNode<T, ScopedSchemaName<TScope, Name>>,
8989
object & InsertableObjectFromSchemaRecord<T>,
9090
true,
91-
T
91+
T,
92+
never,
93+
TCustomMetadata
9294
> {
9395
return objectSchema(scoped<TScope, TName, Name>(this, name), fields, true, {
9496
...defaultSchemaFactoryObjectOptions,
@@ -110,7 +112,9 @@ export class SchemaFactoryBeta<
110112
System_Unsafe.TreeObjectNodeUnsafe<T, ScopedSchemaName<TScope, Name>>,
111113
object & System_Unsafe.InsertableObjectFromSchemaRecordUnsafe<T>,
112114
false,
113-
T
115+
T,
116+
never,
117+
TCustomMetadata
114118
> {
115119
type TScopedName = ScopedSchemaName<TScope, Name>;
116120
return this.object(

packages/dds/tree/src/test/simple-tree/api/schemaFactory.spec.ts

Lines changed: 90 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,42 @@ import { EmptyKey } from "../../../core/index.js";
105105
type FromArray = TreeNodeFromImplicitAllowedTypes<[typeof Note, typeof Note]>;
106106
type _check5 = requireTrue<areSafelyAssignable<FromArray, Note>>;
107107
}
108+
// TreeNodeFromImplicitAllowedTypes with a class
109+
{
110+
class NoteCustomized extends schema.object("Note", { text: schema.string }) {
111+
public test: boolean = false;
112+
}
113+
114+
type _check = requireAssignableTo<typeof NoteCustomized, TreeNodeSchema>;
115+
type _checkNodeType = requireAssignableTo<
116+
typeof NoteCustomized,
117+
TreeNodeSchema<string, NodeKind, NoteCustomized>
118+
>;
119+
120+
type Instance = InstanceType<typeof NoteCustomized>;
121+
type _checkInstance = requireTrue<areSafelyAssignable<Instance, NoteCustomized>>;
122+
123+
type Test = TreeNodeFromImplicitAllowedTypes<typeof NoteCustomized>;
124+
type _check2 = requireTrue<areSafelyAssignable<Test, NoteCustomized>>;
125+
126+
type _check3 = requireTrue<
127+
areSafelyAssignable<
128+
TreeNodeFromImplicitAllowedTypes<[typeof NoteCustomized]>,
129+
NoteCustomized
130+
>
131+
>;
132+
type _check4 = requireTrue<
133+
areSafelyAssignable<
134+
TreeNodeFromImplicitAllowedTypes<[() => typeof NoteCustomized]>,
135+
NoteCustomized
136+
>
137+
>;
138+
139+
type FromArray = TreeNodeFromImplicitAllowedTypes<
140+
[typeof NoteCustomized, typeof NoteCustomized]
141+
>;
142+
type _check5 = requireTrue<areSafelyAssignable<FromArray, NoteCustomized>>;
143+
}
108144

109145
// TreeFieldFromImplicitField
110146
{
@@ -383,29 +419,78 @@ describe("schemaFactory", () => {
383419
);
384420
});
385421

386-
it("Node schema metadata", () => {
422+
it("Node schema metadata - beta", () => {
387423
const factory = new SchemaFactoryBeta("");
388424

389425
const fooMetadata = {
390426
description: "An object called Foo",
391427
custom: {
392428
baz: true,
393429
},
394-
};
430+
} as const;
395431

396432
class Foo extends factory.object(
397433
"Foo",
398434
{ bar: factory.number },
399435
{ metadata: fooMetadata },
400436
) {}
401437

438+
// Ensure `Foo.metadata` is typed as we expect, and we can access its fields without casting.
439+
const description = Foo.metadata.description;
440+
type _check1 = requireTrue<areSafelyAssignable<typeof description, string | undefined>>;
441+
442+
const custom = Foo.metadata.custom;
443+
444+
// Currently it is impossible to have required custom metadata: it always includes undefined as an option.
445+
// TODO: having a way to make metadata required would be nice.
446+
447+
type _check2 = requireTrue<
448+
areSafelyAssignable<typeof custom, { baz: true } | undefined>
449+
>;
450+
assert(custom !== undefined);
451+
452+
const baz = custom.baz;
453+
type _check3 = requireTrue<areSafelyAssignable<typeof baz, true>>;
454+
455+
// This must be checked after the types are checked to avoid it narrowing and making the type checks above not test anything.
402456
assert.deepEqual(Foo.metadata, fooMetadata);
457+
});
458+
459+
it("Node schema metadata - alpha", () => {
460+
const factory = new SchemaFactoryAlpha("");
461+
462+
const fooMetadata = {
463+
description: "An object called Foo",
464+
custom: {
465+
baz: true,
466+
},
467+
} as const;
468+
469+
class Foo extends factory.objectAlpha(
470+
"Foo",
471+
{ bar: factory.number },
472+
{ metadata: fooMetadata },
473+
) {}
403474

404475
// Ensure `Foo.metadata` is typed as we expect, and we can access its fields without casting.
405476
const description = Foo.metadata.description;
406-
const baz = Foo.metadata.custom.baz;
407-
type _check1 = requireTrue<areSafelyAssignable<typeof description, string>>;
408-
type _check2 = requireTrue<areSafelyAssignable<typeof baz, boolean>>;
477+
type _check1 = requireTrue<areSafelyAssignable<typeof description, string | undefined>>;
478+
479+
const custom = Foo.metadata.custom;
480+
481+
// Currently it is impossible to have required custom metadata: it always includes undefined as an option.
482+
// TODO: having a way to make metadata required would be nice.
483+
484+
type _check2 = requireTrue<
485+
areSafelyAssignable<typeof custom, { baz: true } | undefined>
486+
>;
487+
assert(custom !== undefined);
488+
489+
const baz = custom.baz;
490+
type _check3 = requireTrue<areSafelyAssignable<typeof baz, true>>;
491+
492+
// This must be checked after the types are checked to avoid it narrowing and making the type checks above not test anything.
493+
assert.deepEqual(Foo.metadata, fooMetadata);
409494
});
410495

411496
it("Field schema metadata", () => {

packages/dds/tree/src/test/simple-tree/api/schemaFactoryRecursive.spec.ts

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
type AllowedTypesFull,
2929
type ImplicitAllowedTypes,
3030
type AllowedTypes,
31+
SchemaFactoryBeta,
3132
} from "../../../simple-tree/index.js";
3233
import {
3334
allowUnused,
@@ -498,8 +499,8 @@ describe("SchemaFactory Recursive methods", () => {
498499
}
499500
});
500501

501-
it("Node schema metadata", () => {
502-
const factory = new SchemaFactoryAlpha("");
502+
it("Node schema metadata - beta", () => {
503+
const factory = new SchemaFactoryBeta("");
503504
class Foo extends factory.objectRecursive(
504505
"Foo",
505506
{ bar: [() => Foo] },
@@ -511,14 +512,59 @@ describe("SchemaFactory Recursive methods", () => {
511512
},
512513
) {}
513514

515+
const custom = Foo.metadata.custom;
516+
517+
// Currently it is impossible to have required custom metadata: it always includes undefined as an option.
518+
// TODO: having a way to make metadata required would be nice.
519+
type _check1 = requireTrue<
520+
areSafelyAssignable<typeof custom, { baz: true } | undefined>
521+
>;
522+
assert(custom !== undefined);
523+
524+
// Ensure `Foo.metadata` is typed as we expect, and we can access its fields without casting.
525+
const baz = custom.baz;
526+
527+
type _check2 = requireTrue<areSafelyAssignable<typeof baz, true>>;
528+
529+
// This must be checked after the types are checked to avoid it narrowing and making the type checks above not test anything.
514530
assert.deepEqual(Foo.metadata, {
515531
description: "A recursive object called Foo",
516532
custom: { baz: true },
517533
});
534+
});
535+
536+
it("Node schema metadata - alpha", () => {
537+
const factory = new SchemaFactoryAlpha("");
538+
class Foo extends factory.objectRecursive(
539+
"Foo",
540+
{ bar: [() => Foo] },
541+
{
542+
metadata: {
543+
description: "A recursive object called Foo",
544+
custom: { baz: true },
545+
},
546+
},
547+
) {}
548+
549+
const custom = Foo.metadata.custom;
550+
551+
// Currently it is impossible to have required custom metadata: it always includes undefined as an option.
552+
// TODO: having a way to make metadata required would be nice.
553+
type _check1 = requireTrue<
554+
areSafelyAssignable<typeof custom, { baz: true } | undefined>
555+
>;
556+
assert(custom !== undefined);
518557

519558
// Ensure `Foo.metadata` is typed as we expect, and we can access its fields without casting.
520-
const baz = Foo.metadata.custom.baz;
521-
type _check1 = requireTrue<areSafelyAssignable<typeof baz, true>>;
559+
const baz = custom.baz;
560+
561+
type _check2 = requireTrue<areSafelyAssignable<typeof baz, true>>;
562+
563+
// This must be checked after the types are checked to avoid it narrowing and making the type checks above not test anything.
564+
assert.deepEqual(Foo.metadata, {
565+
description: "A recursive object called Foo",
566+
custom: { baz: true },
567+
});
522568
});
523569
});
524570
describe("ValidateRecursiveSchema", () => {

packages/framework/fluid-framework/api-report/fluid-framework.alpha.api.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,9 +1296,9 @@ export class SchemaFactoryAlpha<out TScope extends string | undefined = string |
12961296

12971297
// @beta
12981298
export class SchemaFactoryBeta<out TScope extends string | undefined = string | undefined, TName extends number | string = string> extends SchemaFactory<TScope, TName> {
1299-
object<const Name extends TName, const T extends RestrictiveStringRecord<ImplicitFieldSchema>, const TCustomMetadata = unknown>(name: Name, fields: T, options?: ObjectSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, TreeObjectNode<T, ScopedSchemaName<TScope, Name>>, object & InsertableObjectFromSchemaRecord<T>, true, T>;
1299+
object<const Name extends TName, const T extends RestrictiveStringRecord<ImplicitFieldSchema>, const TCustomMetadata = unknown>(name: Name, fields: T, options?: ObjectSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, TreeObjectNode<T, ScopedSchemaName<TScope, Name>>, object & InsertableObjectFromSchemaRecord<T>, true, T, never, TCustomMetadata>;
13001300
// (undocumented)
1301-
objectRecursive<const Name extends TName, const T extends RestrictiveStringRecord<System_Unsafe.ImplicitFieldSchemaUnsafe>, const TCustomMetadata = unknown>(name: Name, t: T, options?: ObjectSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, System_Unsafe.TreeObjectNodeUnsafe<T, ScopedSchemaName<TScope, Name>>, object & System_Unsafe.InsertableObjectFromSchemaRecordUnsafe<T>, false, T>;
1301+
objectRecursive<const Name extends TName, const T extends RestrictiveStringRecord<System_Unsafe.ImplicitFieldSchemaUnsafe>, const TCustomMetadata = unknown>(name: Name, t: T, options?: ObjectSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, System_Unsafe.TreeObjectNodeUnsafe<T, ScopedSchemaName<TScope, Name>>, object & System_Unsafe.InsertableObjectFromSchemaRecordUnsafe<T>, false, T, never, TCustomMetadata>;
13021302
record<const T extends TreeNodeSchema | readonly TreeNodeSchema[]>(allowedTypes: T): TreeNodeSchemaNonClass<ScopedSchemaName<TScope, `Record<${string}>`>, NodeKind.Record, TreeRecordNode<T> & WithType<ScopedSchemaName<TScope, `Record<${string}>`>, NodeKind.Record>, RecordNodeInsertableData<T>, true, T, undefined>;
13031303
record<const Name extends TName, const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(name: Name, allowedTypes: T, options?: NodeSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Record, TreeRecordNode<T> & WithType<ScopedSchemaName<TScope, Name>, NodeKind.Record>, RecordNodeInsertableData<T>, true, T, undefined, TCustomMetadata>;
13041304
recordRecursive<Name extends TName, const T extends System_Unsafe.ImplicitAllowedTypesUnsafe, const TCustomMetadata = unknown>(name: Name, allowedTypes: T, options?: NodeSchemaOptions<TCustomMetadata>): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Record, TreeRecordNodeUnsafe<T> & WithType<ScopedSchemaName<TScope, Name>, NodeKind.Record, unknown>, {

0 commit comments

Comments
 (0)