对不起,如果这些都没有意义,但我对如何在此处进行打字感到非常困惑。
我有一些这样的接口:
interface AAA { a: string; }
interface BBB { b: string; }
interface CCC { c: string; }
interface DDD { d: string; }
这是我的“NOT”类型用例:
// I'm not even sure if this is a correct or useful type...
type SomeType<T> = T extends { a: string } ? AAA
: T extends { b: string } ? BBB
: T extends { c: string } ? CCC
: DDD;
class AlphabetNode<T> {
// How do I specify "NOT<T>" in typescript? I tried using "Exclude<any, T>" but it
// doesn't prevent "T" objects from being pushed into the array.
public children: SomeType<NOT<T>>[] = [];
constructor(public data: SomeType<T>) {}
}
// I would prefer to not have to specify the type "AAA" if there exists a solution.
const x: AlphabetNode<AAA> = new AlphabetNode({ a: 'I like the letter A' });
// Valid
x.children.push({ b: 'This should be valid' });
x.children.push({ c: 'This should also be valid' });
// Both of these statements should be invalid, but as my types are currently set up,
// typescript is fine with both.
x.children.push({ b: 'Uh', c: 'Oh' });
x.children.push({ a: 'Why is this valid?' });
答案 0 :(得分:0)
好的,我一直在玩这个,我找到了一个我现在必须使用的部分解决方案......
interface AAA { a: string }
interface BBB { b: string }
interface CCC { c: string }
interface DDD { d: string }
type WhichAlphabet<T> = T extends AAA ? AAA
: T extends BBB ? BBB
: T extends CCC ? CCC
: T extends DDD ? DDD : never;
class AlphabetNode<T> {
public children: Exclude<WhichAlphabet<any>, T>[] = [];
constructor(public data: WhichAlphabet<T>) {}
}
const a = new AlphabetNode<AAA>({ a: 'Letter a' });
a.children.push({ b: 'Letter b' }); // Ok
a.children.push({ c: 'Letter c' }); // Ok
a.children.push({ d: 'Letter d' }); // Ok
a.children.push({ x: 'Letter x' }); // invalid
a.children.push({ a: 'Another letter a' }); // invalid
所以这一切都很好,但唯一的问题是......
a.children.push({ b: 'Another letter b', c: 'Another letter c' }); // Ok
在这一点上,我只需要坚持下去,因为我已经浪费了太多时间。也许这会帮助某人想出“真实”的答案。