我在TypeScript中有以下接口:

interface IX {
    a: string,
    b: any,
    c: AnotherType
}

我声明了一个该类型的变量并初始化了所有属性

let x: IX = {
    a: 'abc',
    b: null,
    c: null
}

然后在稍后的init函数中为它们赋值

x.a = 'xyz'
x.b = 123
x.c = new AnotherType()

但我不喜欢在声明对象时为每个属性指定一堆默认空值,因为它们稍后将被设置为实值。我能告诉接口默认属性我不提供为空吗?是什么让我这样做:

let x: IX = {
    a: 'abc'
}

而不会产生编译器错误。现在它告诉我了

TS2322:类型“{}”不能赋值给类型 “九”。属性“b”在类型“{}”中缺失。


当前回答

您还可以使用helper方法/函数返回具有默认属性值的对象,然后调用代码可以根据需要重写默认值。这就是我在当前项目中遇到同样问题时所遵循的方法。通过这种方式,对默认属性值对象进行编码是一次性的事情,您可以在整个应用程序中重用该对象。

其他回答

在有很多参数的情况下,最好让用户只插入几个参数,而且没有特定的顺序。

例如,不好的做法:

foo(a?, b=1, c=99, d=88, e?)
foo(null, null, null, 3)

因为你必须在你真正想要的参数(d)之前提供所有参数。

好的做法是:

foo({d=3})

实现它的方法是通过接口。 你需要将参数定义为一个接口,像这样:

interface Arguments {
    a?;
    b?; 
    c?;
    d?;
    e?;
}

并像这样定义函数:

foo(arguments: Arguments)

现在接口变量不能得到默认值,那么我们如何定义默认值呢?

简单,我们为整个接口定义默认值:

foo({
        a,
        b=1,
        c=99,
        d=88,
        e                    
    }: Arguments)

现在如果用户通过:

foo({d=3})

实际参数为:

{
    a,
    b=1,
    c=99,
    d=3,
    e                    
}

另一个不声明接口的选项是:

foo({
        a=undefined,
        b=1,
        c=99,
        d=88,
        e=undefined                    
    })

跟进: 在前面的函数定义中,我们为参数对象的字段定义了默认值,但没有为对象本身定义默认值。 因此,我们将从下面的调用中得到一个提取错误(例如不能读取未定义的属性'b'):

foo()

有两种可能的解决方案:

1.

const defaultObject = {a=undefined, b=1, c=99, d=88, e=undefined}
function foo({a=defaultObject.a, b=defaultObject.b, c=defaultObject.c, d=defaultObject.d, e=defaultObject.e} = defaultObject)
function foo(object = {}) {
    object = { b=1, c=99, d=88, ...object }
    //Continue the function code..
}

跟进: 如果你需要类型和默认值(并且你不想声明一个接口),你可以这样写:

function foo(params: {a?: string, b?: number, c?: number, d?: number, e?: string}) {
    params = { b:1, c:99, d:88, ...params }
    //Continue the function code..
}

你可以用一个类实现接口,然后你可以在构造函数中初始化成员:

class IXClass implements IX {
    a: string;
    b: any;
    c: AnotherType;

    constructor(obj: IX);
    constructor(a: string, b: any, c: AnotherType);
    constructor() {
        if (arguments.length == 1) {
            this.a = arguments[0].a;
            this.b = arguments[0].b;
            this.c = arguments[0].c;
        } else {
            this.a = arguments[0];
            this.b = arguments[1];
            this.c = arguments[2];
        }
    }
}

另一种方法是使用工厂函数:

function ixFactory(a: string, b: any, c: AnotherType): IX {
    return {
        a: a,
        b: b,
        c: c
    }
}

然后你可以简单地:

var ix: IX = null;
...

ix = new IXClass(...);
// or
ix = ixFactory(...);

我的解决方案:

我在对象上创建了包装器。指派以修复键入问题。

export function assign<T>(...args: T[] | Partial<T>[]): T {
  return Object.assign.apply(Object, [{}, ...args]);
}

用法:

env.base.ts

export interface EnvironmentValues {
export interface EnvironmentValues {
  isBrowser: boolean;
  apiURL: string;
}

export const enviromentBaseValues: Partial<EnvironmentValues> = {
  isBrowser: typeof window !== 'undefined',
};

export default enviromentBaseValues;

env.dev.ts

import { EnvironmentValues, enviromentBaseValues } from './env.base';
import { assign } from '../utilities';

export const enviromentDevValues: EnvironmentValues = assign<EnvironmentValues>(
  {
    apiURL: '/api',
  },
  enviromentBaseValues
);

export default enviromentDevValues;

另一种方法是使用https://www.npmjs.com/package/merge 这和上一个答案是一样的,但是更简洁一些。

让我们安装合并

yarn add -D merge

接下来让我们创建一个带有一些选项的接口。 我们把它放到 / / index.ts类型

export interface ExampleOpts {
    opt1: string,
    opt2: string,
    opt3: string,
}

接下来让我们创建一组默认值 你可以把它放在同一个文件中,但让我们保持类型分离,并将其放入 / config / index.ts

import { ExampleOpts } from '../types'

// Defaults
export const ExampleOptsDefault : ExampleOpts = {
    opt1: 'default value 1',
    opt2: 'default value 2',
    opt3: 'default value 3',
}

接下来让我们用一个函数将它们全部连接在一起 。/ index.ts

import { ExampleOpts } from './types'
import { ExampleOptsDefault } from './config'
import merge from 'merge'

// The ? makes the parameter optional
export function test1(options?: ExampleOpts) {
    // merge tries to load in the defaults first, then options next if it's defined
    const merged_opts: ExampleOpts = merge.recursive(ExampleOptsDefault, options)
    // log the result to the console
    console.log(merged_opts)
}

我需要这个React组件。

你可以使用Nullish Coalescing Operator,它会在左手值为Null或Undefined时赋一个默认值:

interface IX {
    a: string,
    b?: any,
    c?: AnotherType
}

const ixFunction: React.FC<IX> = (props) => {
  console.log(props.b?? "DefaultValue")
}

但这只适用于只在一个地方使用变量的情况。