【发布时间】:2019-10-01 16:56:45
【问题描述】:
我在我的 React + Apollo 项目中使用 TypeScript,我正在使用 graphql-code-generator 生成以下类型:
type Maybe<T> = T | null;
type Scalars = {
ID: string,
String: string,
Boolean: boolean,
Int: number,
Float: number,
DateTime: any,
ISO8601DateTime: any,
Date: any,
Json: any,
};
type RelayNode = {
id: Scalars['ID'],
};
type Project = RelayNode & {
__typename?: 'Project',
number: Scalars['Int'],
title: Scalars['String']
projectManagers?: Maybe<Array<{ id: Scalars['String'], name: Scalars['String'] }>>,
};
type GetProjectQuery = (
{ __typename?: 'Query' }
& { project: Maybe<(
{ __typename?: 'Project' }
& Pick<Project, 'number' | 'title' | 'projectManagers'>
)> }
);
type ProjectInput = {
title?: Maybe<Scalars['String']>,
number?: Maybe<Scalars['Int']>,
projectManagerIds?: Maybe<Array<Scalars['String']>>,
};
现在我想构建一个表单,它采用project 作为我的初始值。示例项目可能看起来像...
const project: GetProjectQuery['project'] = {
__typename: 'Project',
number: 123,
title: 'My awesome project',
projectManagers: [{ id: '123', name: 'Me & myself'}]
}
...但是我的表单只允许ProjectInput 而不是Project(因为输入变量可能与输出不同),所以我正在这样做...
const input: ProjectInput = project
...但这似乎是有效的——Typescript 不会抛出任何错误。但我想强制警告该对象不应定义projectManagers。目标是强制输入对象 hat 没有定义 projectManagers 但 projectManagerIds 定义。
我创建了一个最小的测试用例here,其中“拒绝”有效:
type Project = {
title?: string
number?: number
};
const project: Project = {
title: 'foo',
number: 123,
foo: 'bar' // this key isn't allowed
}
但我不明白为什么这不适用于我上面生成的类型。
【问题讨论】:
-
TS 只对文字赋值进行严格的属性检查。 IE。您分配
= { ... }的最后一个是“文字分配”,第一个= project不是,因为您正在传递一个单独的变量。为了防止某些特定的不想要的键,即使是通过变量赋值,你可以明确地禁止它们:{ unwanted?: never } -
哦。哇。这让我大吃一惊。事实上,这是有效的:typescriptlang.org/play/#code/…。谢谢!
标签: typescript