typescript 如何使一个对象属性依赖于泛型类型中的另一个属性?

83qze16e  于 2022-11-30  发布在  TypeScript
关注(0)|答案(1)|浏览(124)

我正在尝试创建一个对象,该对象的属性依赖于另一个属性。
这是一个非常简单的例子,我尝试到目前为止。
我期望从name推断出Tvalue应该限制为TypeA中的有效值。

type TypeA = {
  some: 'some2';
  thing: 'thing2';
};

type TypeAUnion = keyof TypeA;

type TestType<T extends TypeAUnion = TypeAUnion> = {
  name: T;
  value: TypeA[T];
};

const test1: TestType = {
  name: 'some',
  value: 'some2',
};

const test2: TestType = {
  name: 'some',
  value: 'thing2', // shouldn't be allowed here
};

编辑:

这是一个更好的例子来说明我想做的事情。

type StateType = {
  thingA: string;
  thingB: number;
};

type StateKeysUnion = keyof StateType;

const state: StateType = {
  thingA: 'somestring',
  thingB: 10,
};

type PayloadType<T extends StateKeysUnion = StateKeysUnion> = {
  key: T;
  value: StateType[T];
};

const setThing = (payload: PayloadType) => {
  state[payload.key] = payload.value;
};

setThing({
  key: 'thingA',
  // expected to only accept string
  value: true,
});

setThing({
  key: 'thingB',
  // expected to only accept number
  value: 'asdas',
});
1sbrub3j

1sbrub3j1#

你要做的事情不能用泛型类型来表达。

type Narrow<T extends string = string> = T;

// str type narrowing
type Out = Narrow<"hi">;
// type Out = "hi"

// default case
type Out2 = Narrow;
// type Out2 = string

// **values don't narrow the type**
let t: Narrow = "hi"
type Out3 = typeof t;
// type Out3 = string (default)

如果要在通用字段中指定some

const test2: TestType<"some"> = {
  name: 'some',
  value: 'thing2', // it now gives the error you're looking for.
};

但是,因为您不是,T默认为keyof TypeA,并允许您混合和匹配。
您应该改用@jcalz union approach。:)

相关问题