我有一个接口function() {
var n = e("./styles/css/styles.scss")
, t = document.createElement("style");
t.innerHTML = n,
document.head.appendChild(t)
}(),
和一个对象[Report Only] Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self' 'nonce-b123d558a63bc7e84aa7' ". Either the 'unsafe-inline' keyword, a hash ('sha256-SamqqFx+xVKq8AnoIWgeammNlDl/h4AP94HthfQO43Q='), or a nonce ('nonce-...') is required to enable inline execution.
,其类型未知。如果V
的任何属性是x
的键,我想抛出运行时错误。 TypeScript最友好的方式是什么?
这是一个明显的例子:
x
尽管我希望使用类型系统来使此检查隐式化,但我知道有上百万种使用JavaScript的方法(例如,保留无效字符串数组等)。
编辑:我对使用无效键数组的担心是,如果我更改接口,我不想忘记更新数组。如果我使用数组,则需要一种类型检查的方法来确保它与接口保持一致。
答案 0 :(得分:2)
一旦您接受了一个不幸的事实,您就需要维护一些与V
相关的运行时工件,因为V
本身就是erased,并假设您实际上无法使用要定义 V
的运行时工件,如果您的运行时工件和V
不同步,那么最好的办法就是让编译器大吼大叫。这是一种实现方法:
interface V {
a: number;
b: string;
}
const keysOfV = ["a", "b"] as const;
type MutuallyAssignable<T extends U, U extends V, V = T> = void;
// the following line will give an error if keysOfV is wrong
type KeysOfVIsGood = MutuallyAssignable<keyof V, typeof keysOfV[number]>; // okay
请注意as const
的定义中的keysOfV
。那是const
assertion,需要它(或类似的东西)来使编译器跟踪keysOfV
的文字字符串元素,而不是推断出正确但太宽的类型{{1} }。
然后,string[]
是一种求值为MutuallyAssignable<T, U>
的类型,但我们实际上并不关心它求值的含义。我们关心的是void
是constrained到T
,而U
被约束到U
(通过default参数避开了违反循环约束)。在某些类型T
和MutuallyAssignable<X, Y>
上使用X
时,如果编译器不认识到Y
和X
是可相互分配的,则会出现编译器错误。 。
然后,您可以根据需要使用Y
继续定义和使用hasInvalidProperties()
函数。也许像这样:
keysOfV
主要事件是function hasInvalidProperties(x: object): x is { [K in keyof V]: Record<K, any> }[keyof V] {
return Object.keys(x).some(k => hasInvalidProperties.badKeySet.has(k));
}
hasInvalidProperties.badKeySet = new Set(keysOfV) as Set<string>;
/// test
function getDataFromRequest(): object {
return Math.random() < 0.5 ? { c: "okay" } : { a: "bad" };
}
const x = getDataFromRequest();
if (hasInvalidProperties(x)) {
console.log("not okay");
throw new Error();
}
console.log("okay");
错误时发生的情况。缺少条目时会发生以下情况:
keysOfV
当它有一个额外的条目时,会发生以下情况:
const keysOfV = ["a"] as const;
type MutuallyAssignable<T extends U, U extends V, V = T> = void;
// the following line will give an error if keysOfV is wrong
type KeysOfVIsGood = MutuallyAssignable<keyof V, typeof keysOfV[number]>; // error!
// "b" is not assignable to "a" ------> ~~~~~~~
希望这些错误消息和位置具有足够的描述性,以使您了解在const keysOfV = ["a", "b", "c"] as const;
type MutuallyAssignable<T extends U, U extends V, V = T> = void;
// the following line will give an error if keysOfV is wrong
type KeysOfVIsGood = MutuallyAssignable<keyof V, typeof keysOfV[number]>; // error!
// "c" is not assignable to "a" | "b" ---------> ~~~~~~~~~~~~~~~~~~~~~~
更改时如何解决。
好的,希望能有所帮助;祝你好运!
答案 1 :(得分:1)
如果您愿意使用transformers,则可以在编译时获取接口上的属性列表,然后解析为字符串的运行时列表。因为它依赖于一个用Typescript编写的编译器插件,所以它不是本机TypeScript解决方案,但是它使您不必将接口中的数据复制到字符串列表中。
答案 2 :(得分:0)
无法使用Typescript进行此操作,因为在您的代码运行时,您对类型的了解不再。唯一的方法就是使用其他工具。
我们使用的一个系统是json-schema。我们为进出API的所有内容编写模式,并使用工具自动将JSON-Schema转换为Typescript类型。我们不做相反的事情,因为json模式比打字稿更具表现力。
通过这种方式,我们可以使用1个规范的源代码获得运行时验证和静态类型。