TypeScript WebGL(2)上下文方法不允许资源参数为null,

uqjltbpv  于 6个月前  发布在  TypeScript
关注(0)|答案(2)|浏览(44)

🔎 搜索关键词

WebGL2RenderingContext, attachShader, createShader, null

🕗 版本与回归信息

  • 这是我在尝试的每个版本中的行为(Nightly, 5.4.5, 4.9.5, 3.9.7),我查阅了关于WebGL的FAQ条目

⏯ Playground链接

https://www.typescriptlang.org/play?target=99&jsx=0&ts=5.5.0-dev.20240415#code/KYDwDg9gTgLgBDAnmYcDKALAhgE2FAFWVQF44B1YAIwHEAZAJgCVgA7PKAS1YHMBhCKxigYAbQDkAMSYBBGgFkAogDkCAfTQAJGQBFFTcQF04AHwrV6zNh279BwkGPEA1fQUUANDdr0HDAbgAoQNBIWDgAMwBXVgBjGE5BOAAbCFxMXHwACh5kgC5zWkYWdnxbASERABo4AGcIKKhY4ALamC5eGqQUAoyOIhQASgLKIr78UzhWKOTkuABvQIBIWME2uuwOODJcgDpYqGAsYXGoLO7gQaDlgHobuE4IuEQGuBjVgFsPtngYDAhaqhktxgLUHvAAO7QADWYKoUXgPAgoLgWB4WG46z+qEOn2sx0SrDBxzgGBgMDAtTydwhtN20IwUEEAN20B4Nwh1FyHM40M4N00WHYwN4FQcMDoAJgAGIdIIAKSKBjygAcAAZ5QBOTUwNSxDDAWLQtQRaBqaazNSCPWHAmCYJLO4PJ5ZWqbCYkT1TGbJQYLW73JZ-JkQqbAUOKKBMs4AIjdmSgDzBFuSNReUXEADcgVK4KtKo4Y1cA3AAL7LPbxjhoBpNYCu91QGr1RrNYtLPafMCcZLAU4NhPF5b59a1KKxZq1ME7ZK7HjAGCnAAKWCgWG+wjOVfwNT2fAA8vIlwBJOiKDQEGQEACqaHbjzgrvHk9qfsWSyWhxgjVYGwTQSWcthzWCBe12fBoxyWd50XRtj1YU1JR4AcOEGds9jwXsTkbFD8HbL8f29WYglLIA

💻 代码

export type ShaderType = WebGL2RenderingContext['FRAGMENT_SHADER'] | WebGL2RenderingContext['VERTEX_SHADER'];

export function loadShader(gl: WebGL2RenderingContext, source: string, type: ShaderType): WebGLShader | null {
	const shader = gl.createShader(type);

	// if you uncomment those lines it works but goes against the recomendations at https://www.khronos.org/webgl/wiki/HandlingContextLost#Don%E2%80%99t_check_for_null_on_creation

	// if (shader === null) {
	// 	throw new Error("shader is null, you've lost context");
	// }
	gl.shaderSource(shader, source);
	gl.compileShader(shader);

	const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
	if (success) {
		return shader;
	}

	console.error(gl.getShaderInfoLog(shader));
	gl.deleteShader(shader);
	return null;
}

🙁 实际行为

当提供WebGL资源(着色器、程序、缓冲区等)时,接受这些资源的方法在提供 null 时会报告错误,但提供 create* 方法会返回资源(指针)或 null,而规范说明我们不应该在资源创建时检查 null,因为所有函数都接受 null 作为参数(无操作)。
示例:

gl.shaderSource(shader, source);

参数类型为 'WebGLShader | null' 的参数不能分配给参数类型为 'WebGLShader' 的参数。
类型 'null' 不能分配给类型 'WebGLShader'。

🙂 预期行为

将资源作为参数的方法应该允许传递 null。这将与MDN的文档相区分,但符合API和WebGL(2)规范的实际行为。

rta7y2nd

rta7y2nd1#

TypeScript经常禁止根据规范有效的代码。要问的问题是:如果他们传入null,人们会认为这是他们代码中的潜在错误吗?我会说会。

l7wslrjt

l7wslrjt2#

在库作者编写的代码中,我同意这一点,但我们讨论的是原生API。正如我指出的,官方维基建议在资源创建时不要检查空值,因为API旨在支持资源中的空值。
您应该只从这些函数中得到空值,如果上下文丢失,那么没有理由检查。WebGL设计成即使程序或着色器为空,大部分情况下也能正常运行。
khronos.org --- https://www.khronos.org/webgl/wiki/HandlingContextLost#Don%E2%80%99t_check_for_null_on_creation
因此,由于lib.dom的类型定义不包括接受资源或空值的方法(在示例shaderSourcecompileShader中,typescript会在官方文档推荐的代码上引发错误。

相关问题