我可以做类似“可能未定义的字符串”的类型吗

时间:2018-06-19 20:23:31

标签: typescript

注意:我已打开--strictNullChecks

我有这样的功能:

export function ensure<T, F extends T>(maybe: T | undefined, fallback: F): T {
  if (isDefined<T>(maybe)) {
    return maybe
  }

  if (fallback === undefined) {
    throw new Error('Could not ensure a value; please supply a fallback for the given variable')
  }

  return fallback
}

我用它来摆脱可能不确定的值的undefined部分。

const user = ensure(possiblyUndefinedUser, defaultUser)

我想要以下内容,

const user = ensure(certainlyDefinedUser, defaultUser)

是编译时错误。即,我希望使用带有编译器认为具有值的值的此函数是非法的。 (这将迫使我正确键入函数,请参见下文)

我已经尝试了一些通用参数的变体,以得到类似T | undefined的类型,其中类型T的值不能分配给它。我意识到这可能是不可能的,但我想我会咨询社区,而不是继续辛苦工作。


我的目标是:如果我想通过isNilensure之类的函数传递参数,那么我想被迫将参数类型更改为可选。如果参数不是可选的,那么我应该100%确信无需进行空检查。

1 个答案:

答案 0 :(得分:3)

如果不能不确定第一个参数,我们可以使用条件类型来触发第二个参数的错误。

function isDefined<T>(v: T) : v is Exclude<T, undefined> {
    return !!v;
}

export function ensure<T, F extends (undefined extends T ? T : 'First param can\'t be undefined')>(maybe: T, fallback: F): Exclude<T, undefined> {
    if (isDefined<T>(maybe)) {
        return maybe
    }

    if (fallback === undefined) {
        throw new Error('Could not ensure a value; please supply a fallback for the given variable')
    }
    //We need a type assertion here as F tehnically might not extend T
    return fallback as any;
}

declare var defaultUser: string|undefined;
declare var possiblyUndefinedUser: string| undefined
const user = ensure(possiblyUndefinedUser, defaultUser) //ok

declare var certainlyDefinedUser: string;
const user2 = ensure(certainlyDefinedUser, defaultUser); //error

游乐场link,您需要手动选择严格的null检查。