/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import type { RestrictiveStringRecord } from "../../../util/index.js";
import { NodeKind } from "../../core/index.js";
import type { TreeNodeSchemaClass, TreeNodeSchema, TreeNodeSchemaNonClass, WithType, TreeNode, ImplicitAllowedTypes, InsertableTreeNodeFromImplicitAllowedTypes, TreeNodeFromImplicitAllowedTypes } from "../../core/index.js";
import type { SchemaType, SimpleRecordNodeSchema } from "../../simpleSchema.js";
/**
 * A {@link TreeNode} which models a TypeScript {@link https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type | record}.
 *
 * @remarks
 * Due to {@link https://github.com/microsoft/TypeScript/issues/43826}, we can't enable implicit construction of {@link TreeNode|TreeNodes} for setters.
 * Therefore code assigning to these fields must explicitly construct nodes using the schema's constructor or create method,
 * or using some other method like {@link (TreeAlpha:interface).create}.
 *
 * Field Assignment and Deletion
 *
 * Unlike JavaScript's `Record` type, assigning `undefined` to a key in {@link TreeRecordNode} behaves like a `delete` operation,
 * removing the field's contents.
 *
 * This is to stay consistent with {@link TreeObjectNode} behavior.
 *
 * Example:
 * ```ts
 * const Numbers = schemaFactory.record("Numbers", schemaFactory.number);
 * const record = new Numbers({ a:1, b:2 });
 *
 * // This is equivalent to delete record.a, and removes the entry.
 * record.a = undefined
 * ```
 *
 * @beta
 */
export interface TreeRecordNode<TAllowedTypes extends ImplicitAllowedTypes = ImplicitAllowedTypes> extends TreeNode, Record<string, TreeNodeFromImplicitAllowedTypes<TAllowedTypes>> {
    /**
     * Allows the record's entries to be iterated over, including in contexts like `for...of` loops.
     */
    [Symbol.iterator](): IterableIterator<[
        string,
        TreeNodeFromImplicitAllowedTypes<TAllowedTypes>
    ]>;
}
/**
 * Content which can be used to construct a Record node, explicitly or implicitly.
 * @system @beta
 */
export type RecordNodeInsertableData<T extends ImplicitAllowedTypes> = RestrictiveStringRecord<InsertableTreeNodeFromImplicitAllowedTypes<T>>;
/**
 * A schema for customizable {@link (TreeMapNode:interface)}s.
 * @system @sealed @alpha
 */
export interface RecordNodeCustomizableSchema<out TName extends string = string, in out T extends ImplicitAllowedTypes = ImplicitAllowedTypes, out ImplicitlyConstructable extends boolean = true, out TCustomMetadata = unknown> extends TreeNodeSchemaClass<TName, NodeKind.Record, TreeRecordNode<T> & WithType<TName, NodeKind.Record, T>, RecordNodeInsertableData<T>, ImplicitlyConstructable, T, undefined, TCustomMetadata>, SimpleRecordNodeSchema<SchemaType.View, TCustomMetadata> {
}
/**
 * A schema for POJO emulation mode {@link (TreeMapNode:interface)}s.
 * @system @sealed @alpha
 */
export interface RecordNodePojoEmulationSchema<out TName extends string = string, in out T extends ImplicitAllowedTypes = ImplicitAllowedTypes, out ImplicitlyConstructable extends boolean = true, out TCustomMetadata = unknown> extends TreeNodeSchemaNonClass<TName, NodeKind.Record, TreeRecordNode<T> & WithType<TName, NodeKind.Record, T>, RecordNodeInsertableData<T>, ImplicitlyConstructable, T, undefined, TCustomMetadata>, SimpleRecordNodeSchema<SchemaType.View, TCustomMetadata> {
}
/**
 * A schema for {@link (TreeRecordNode:interface)}s.
 * @privateRemarks
 * This could have generic arguments added and forwarded.
 * The expected use-cases for this don't need them however, and if they did want an argument it would probably be the allowed types;
 * perhaps if moving to an order independent way to pass generic arguments, adding support for them here would make sense.
 * @alpha
 */
export type RecordNodeSchema<TName extends string = string, T extends ImplicitAllowedTypes = ImplicitAllowedTypes, ImplicitlyConstructable extends boolean = true, TCustomMetadata = unknown> = RecordNodeCustomizableSchema<TName, T, ImplicitlyConstructable, TCustomMetadata> | RecordNodePojoEmulationSchema<TName, T, ImplicitlyConstructable, TCustomMetadata>;
/**
 * @alpha
 */
export declare const RecordNodeSchema: {
    /**
     * `instanceof`-based narrowing support for {@link (RecordNodeSchema:type)} in JavaScript and TypeScript 5.3 or newer.
     */
    readonly [Symbol.hasInstance]: (value: TreeNodeSchema) => value is RecordNodeSchema<string, ImplicitAllowedTypes, true, unknown>;
};
/**
 * Narrows a {@link (TreeNodeSchema:interface)} to an {@link (RecordNodeSchema:interface)}.
 * @privateRemarks
 * If at some point we want to have internal only APIs for RecordNodeSchema (like done for objects),
 * this can include those since its not the public-facing API.
 */
export declare function isRecordNodeSchema(schema: TreeNodeSchema): schema is RecordNodeSchema;
//# sourceMappingURL=recordNodeTypes.d.ts.map