English 中文(简体)
单一财产
原标题:Make a single property optional in TypeScript
  • 时间:2017-04-01 17:24:06
  •  标签:
  • typescript

In TypeScript, 2.2...

请允许我说,我有一个人类型:

interface Person {
  name: string;
  hometown: string;
  nickname: string;
}

而我也希望创造一种恢复一个人的工作功能,但并不需要一个镍:

function makePerson(input: ???): Person {
  return {...input, nickname: input.nickname || input.name};
}

What should be the type of input? I m looking for a dynamic way to specify a type that is identical to Person except that nickname is optional (nickname?: string | undefined). The closest thing I ve figured out so far is this:

type MakePersonInput = Partial<Person> & {
  name: string;
  hometown: string;
}

但是,这并不是我所期望的,因为我必须具体说明所有类型的要求<>/em>,而不是选择的类型。

最佳回答

你们也可以做这样的事情,只是其中的一部分。

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>

interface Person {
  name: string;
  hometown: string;
  nickname: string;
}

type MakePersonInput = PartialBy<Person,  nickname >
问题回答

我的描述 3.5+ 选择用途

type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;

// and your use case
type MakePersonInput = Optional<Person,  nickname >

// and if you wanted to make the hometown optional as well
type MakePersonInput = Optional<Person,  hometown  |  nickname >

关于插头和游戏解决办法,考虑使用下列网址:utility-types。 一揽子:

npm i utility-types --save

然后简单地利用Optional<T, K>:

import { Optional } from  utility-types ;

type Person = {
  name: string;
  hometown: string;
  nickname: string;
}

type PersonWithOptionalNickname = Optional<Person,  nickname >;

// Expect:
//
// type PersonWithOptionalNickname {
//   name: string;
//   hometown: string;
//   nickname?: string;
// }

Update:

如同第2.8版一样,通过 有条件类型,这种支持更为简明。 迄今为止,这似乎也比以往的执行更为可靠。

type Overwrite<T1, T2> = {
    [P in Exclude<keyof T1, keyof T2>]: T1[P]
} & T2;

interface Person {
  name: string;
  hometown: string;
  nickname: string;
}

type MakePersonInput = Overwrite<Person, {
  nickname?: string;
}>

function makePerson(input: MakePersonInput): Person {
  return {...input, nickname: input.nickname || input.name};
}

此前,<代码>MakePersonInput相当于:

type MakePersonInput = {
    name: string;
    hometown: string;
} & {
    nickname?: string;
}

<><>>

至于第2.4.1类文字,它像Gite Hub的用户ahejlsberg所建议的另一种选择一样,在类型的分量上:

type Diff<T extends string, U extends string> = ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T];
type Overwrite<T, U> = { [P in Diff<keyof T, keyof U>]: T[P] } & U;

interface Person {
  name: string;
  hometown: string;
  nickname: string;
}
type MakePersonInput = Overwrite<Person, {
  nickname?: string
}>
function makePerson(input: MakePersonInput): Person {
  return {...input, nickname: input.nickname || input.name};
}

据英特尔利斯公司称,MakePersonInput相当于:

type MakePersonInput = {
    name: string;
    hometown: string;
} & {
    nickname?: string;
}

这看不见,但绝对是得到工作。

在下游方面,Im gonna需要在上挨饿。 在我开始了解它是如何运作的。

如果你使用最近版本的描述,简单的解决办法就是这样做。

function makePerson(input: Omit<Person,  nickname > & { nickname?: string }): Person {
  return {...input, nickname: input.nickname || input.name};
}

基本上,你将“镍”财产从接口中删除,并将之作为任择处理。

如果你想确保与最初的交接点保持一致,你可以这样做。

Omit<Person,  nickname > & Partial<Pick<Person,  nickname >>

如果你改变原有接口中的“镍”推进剂,这将给你带来警告。

你们真正描述的是两种不同的“类型”(即个人类型)。 普通人和一名被点名的人。

interface Person {
    name: string;
    hometown: string;
}

interface NicknamedPerson extends Person {
    nickname: string;
}

那么,如果你真的想要一个名叫“nick”的人,而只是一个人,你就应该执行“人”的界面。

如果你只想把一个人界面hang死,另一种做法是,对一个无名人实施不同的规定:

interface Person {
  name: string;
  hometown: string;
  nickname: string;
}
class NicknamedPerson implements Person {
    constructor(public name: string, public hometown: string, public nickname: string) {}
}

class RegularPerson implements Person {
    nickname: string;
    constructor(public name: string, public hometown: string) {
        this.nickname = name;
    }
}

makePerson(input): Person {
     if(input.nickname != null) {
       return new NicknamedPerson(input.name, input.hometown, input.nickname);
     } else {
       return new RegularPerson(input.name, input.hometown);
     }
}

这使得你仍然能够指定一个镍(在没有镍的情况下,这只是个人名称),并且仍然维护个人接口合同。 这确实与你打算如何使用接口有关。 法典是否关注有镍的人? 否则,第一项建议可能更好。

export type Optional<T, K extends keyof T> = Omit<T, K> & { [P in keyof T]?: T[P] | undefined; }

如果你想要涵盖并非全部通过钥匙的情况,或者该钥匙已经通过,但价值被设定为<条码>。

Covers Both Single & Multiple Properties

仅增加这个可能更灵活的答复:

type Optional<TType, TKey extends (keyof TType)[]> = Omit<TType, TKey[number]> & Partial<Pick<TType, TKey[number]>>

const myPerson1: Optional<Person, [ nickname ]> = {
  name:  Deandre ,
  hometown:  Seoul 
}

const myPerson2: Optional<Person, [ nickname ,  hometown ]> = {
  name:  Ashley 
}

我对你的守则进行了修改:

interface Person {
  name: string;
  hometown: string;
  nickname?: string;
}

TypeScript 5. The question mark "?" denotes an optional property or method in an interface or class.

In the code I provided, the "nickname" property is marked with a question mark, which means that it s optional. It indicates that instances of the Person interface may or may not have a nickname property.

如果个人物体有镍财产,它必须是一种扼杀型。 然而,如果它拥有镍财产,那么它就没有造成汇编错误。 这使得能够界定与个人交接或无nick财产的物体。





相关问题
store data in memory with nestjs

I am trying to persist some data in my nestjs server so I can then use that data in my client app through http requests. I have created a products.service.ts file with the function getAllData() that ...

React Hook Form Error on custom Input component

I am having a problem when I use react hook form + zod in my application, in short the inputs never change value and I get the following error in the console: Warning: Function components cannot be ...

Updatable promises using proxy in JavaScript

EDIT: I ve updated this question, and the old question is moved here. A POC can be found on this jsfiddle or the snippet below GOAL: The goal here is to make or rather simulate a promise that can be ...