У меня есть определение глобального типа, которое представляет собой объект с ключами (то, что я называю prop
), который пользователь должен передать в качестве параметра myFunction()
, и значения, которые используются только моим кодом для проверки типов .
Значения могут иметь только 3 «возможных типа» (содержится в Possible
). Каждый возможный тип имеет свое определение типа.
Я бы хотел, чтобы myFunction()
принимал только в качестве параметра props
, чье значение test
свойство "possible1"
.
generi c type OnlyPossible1Props<T>
показывает способ, которым я бы это реализовал, но он не работает.
Сначала отображается сообщение об ошибке:
Тип 'prop' не может использоваться для тип индекса 'T'. (2536)
И, кроме того, он возвращает string | number
вместо "abc" | "def"
в myFunction()
.
Самая близкая вещь, которую я смог сделать, это кусок кода я закомментировал. Однако при этом он теряет информацию о ключе, потому что я его где-то не храню.
Для простоты отладки, вот ссылка на TypeScript Playground .
type Possible = "possible1" | "possible2" | "possible3";
type ValueBase<T extends Possible, U, V> = {
test: T,
other1: U,
other2: V
};
type Value1<T> = ValueBase<"possible1", T, T>;
type Value2<T> = ValueBase<"possible2", T, [T, T]>;
type Value3<T> = ValueBase<"possible3", T, T[]>;
type Definition = {
[prop: string]: Value1<any> | Value2<any> | Value3<any>
};
interface Example extends Definition {
"abc": {
test: "possible1",
other1: string
other2: string
},
"def": {
test: "possible1",
other1: string
other2: string
},
"ghi": {
test: "possible2",
other1: string
other2: [string, string]
},
"jkl": {
test: "possible3",
other1: string
other2: string[]
}
}
// type OnlyPossible1Props<T> = T extends object ?
// T[keyof T] extends infer A ?
// A extends { test: "possible1" }
// ? A : never : never : never;
type OnlyPossible1Props<T> = T extends object ?
keyof T extends infer prop ?
T[prop] extends infer A ?
A extends { test: "possible1" }
? prop : never : never : never : never;
function myFunction<Prop extends OnlyPossible1Props<Example>>(prop: Prop) { }