-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Not assignable Type #34967
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Except, it isn't. declare const a : [
string | undefined,
string | undefined
];
//Assume this is okay
const b : (
| [string, undefined]
| [undefined, string]
| [string, string]
| [undefined, undefined]
) = a;
if (b[0] == undefined) {
//b is now narrowed to
//[undefined, string] | [undefined, undefined]
a[0] = "hello, world"; //this is allowed
console.log(b[0]); //"hello, world"
} |
This feels like a bug. As per this comment, recent changes to discriminant assignment should probably handle this. For example, this works: const message: string = 'hello world';
console.log(message);
const b = message ? message : undefined;
const c = message ? message : undefined;
interface Pair<L, R> {
0: L,
1: R;
}
const a: Pair<string, undefined> | Pair<undefined, undefined> | Pair<string, string> | Pair<undefined, string> = [b, c]; |
Sounds like a bad idea to allow the assignment, since it's unsound. Somewhat related to #33205 I keep telling everyone assignments like these aren't sound and shouldn't be allowed but it's like I'm talking to the wind >.> |
TypeScript has always allowed covariant references, much like many other languages, which are known to be unsound in the presence of mutation and aliasing. |
Except, in this case, it's a contravariant assigment, isn't it? We're trying to assign declare const a: (string | undefined)[];
//Fails because contravariant assignment
const b: string[] = a;
declare const c: (string | undefined)[];
//Fails because contravariant assignment
const d: undefined[] = c;
declare const e: (string | undefined)[];
//Fails because contravariant assignment
const f: (string[]) | (undefined[]) = e;
declare const g: [string | undefined];
//Fails because contravariant assignment
const h: [string] = g;
declare const i: [string | undefined];
//Fails because contravariant assignment
const j: [undefined] = i;
declare const k: [string | undefined];
//Fails because contravariant assignment
const l: [string]|[undefined] = k; Also related, declare const a : [
string | undefined,
string | undefined
];
//This satisfies the type checker
const b : (
| [string, undefined]
| [undefined, string]
| [string, string]
| [undefined, undefined]
) = (
a[0] == undefined ?
(
a[1] == undefined ?
[a[0], a[1]] :
[a[0], a[1]]
) :
(
a[1] == undefined ?
[a[0], a[1]] :
[a[0], a[1]]
)
);
//Would be nice if this satisfied the type checker
//New object literal should be okay
const c : (
| [string, undefined]
| [undefined, string]
| [string, string]
| [undefined, undefined]
) = (
[a[0], a[1]]
);
//Would be nice if this satisfied the type checker
//New object literal should be okay
const d : (
| [string, undefined]
| [undefined, string]
| [string, string]
| [undefined, undefined]
) = (
[...a]
); |
It's covariant: Syntax directed subtyping algorithms commonly suffer from the problem that they can't prove this relation using the normal decomposition rules, exactly because you decompose into things that try to related |
If mutations are disallowed, I agree with you about the former being a subset of the latter. But I guess TS pretends mutations don't happen. Given a value But,
So, I probably should not consider mutations, since TS pretends they don't happen (in general), but it's hard for me to do so =x |
@rbuckton n.b. there's a typo (missing the |
It looks like this was fixed by #39393, and has been working since 4.0. |
TypeScript 3.7.2
Playground link
Compiler Options:
Input:
Output:
Expected behavior:
To me, Type
[string | undefined, string | undefined]
is assignable to type[string, undefined] | [undefined, string] | [string, string] | [undefined, undefined]
.The text was updated successfully, but these errors were encountered: