import type { Assert, Asserted, Primitive, OptionalIfUndefined } from './prelude.js' import { inspect } from 'util' import object from './object.js' const exact = >>(kvs: T): Assert }>> => value => { if (typeof value !== 'object' || value === null) { throw new TypeError(`Expected object, got ${inspect(value)}.`) } const result = object(kvs)(value) const keys = Object .keys(value) .filter(key => !Object.prototype.hasOwnProperty.call(kvs, key)) if (keys.length) { throw new TypeError(`Unexpected extra keys ${keys.map(String).join(', ')} in ${inspect(value)}.`) } return result as OptionalIfUndefined<{ [k in keyof T]: T[k] extends Primitive ? T[k] : Asserted }> } export default exact