我有一个带参数的方法.我希望Typescript验证传入的对象(在typescript编译时,我理解运行时是一个不同的动物)只满足一个允许的接口.
例:
interface Person {ethnicity: string;}
interface Pet {breed: string;}
function getOrigin(value: Person ^ Pet){...}
getOrigin({}); //Error
getOrigin({ethnicity: 'abc'}); //OK
getOrigin({breed: 'def'}); //OK
getOrigin({ethnicity: 'abc', breed: 'def'});//Error
Run Code Online (Sandbox Code Playgroud)
我意识到这Person ^ Pet
不是有效的Typescript,但这是我认为首先尝试并且看似合理的东西.
Gui*_*lli 10
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
type XOR<T, U> = (T | U) extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U;
Run Code Online (Sandbox Code Playgroud)
现在您的示例起作用了:
interface Person {ethnicity: string;}
interface Pet {breed: string;}
function getOrigin(value: XOR<Person, Pet>) { /* ... */}
getOrigin({}); //Error
getOrigin({ethnicity: 'abc'}); //OK
getOrigin({breed: 'def'}); //OK
getOrigin({ethnicity: 'abc', breed: 'def'});//Error
Run Code Online (Sandbox Code Playgroud)
您可以使用微小的 npm 包 ts-xor
专门用于解决此问题。
有了它,您可以执行以下操作:
import { XOR } from 'ts-xor'
interface A {
a: string
}
interface B {
b: string
}
let A_XOR_B: XOR<A, B>
A_XOR_B = { a: 'a' } // OK
A_XOR_B = { b: 'b' } // OK
A_XOR_B = { a: 'a', b: 'b' } // fails
A_XOR_B = {} // fails
Run Code Online (Sandbox Code Playgroud)
完全披露:我是这个小包的作者。我发现我需要一直从 repo-to-repo 实现 XOR 类型。所以我为我和社区发布了它,这样我也可以使用自述文件和共享的 jsdoc 注释正确地记录它。实现是@Guilherme Agostinelli 从社区分享的内容。
归档时间: |
|
查看次数: |
2331 次 |
最近记录: |