Вы можете использовать сопоставленный тип для извлечения вложенного типа:
type KnownOptions<T> = T extends {
[k in keyof T]: {
[k: string]: infer OptionValue
}
} ? OptionValue : never
// Good:
const a: KnownOptions<Options> = { foo: 'bar' }
const b: KnownOptions<Options> = { baz: 'daz' }
// Expect errors:
const c: KnownOptions<Options> = { foo: 'bad value' }
const d: KnownOptions<Options> = { badKey: 'bar' }
Playground
Это обобщенный тип c, который принимает тип, который имеет два уровня ключей. Условный тип (отмеченный троичным T extends Type ? A : B
) говорит: «если обобщенный тип c является объектом, по крайней мере, на двух уровнях глубины, то возвращайте тип на каждом из этих вторых уровней. В противном случае возвращайте never
тип, потому что тип generi c недопустим.
infer OptionalValue
говорит: «какой бы тип здесь ни был, сохраните его как OptionValue
». Затем он возвращается условным типом после того, как несколько типов имеют был сохранен в нем, создавая объединение каждого типа.
Я должен признать, я не совсем уверен, почему ключ первого уровня должен быть k in keyof T
, но второй уровень может быть просто k: string
Но это был единственный способ заставить его работать должным образом.